---
title: API de plugins
url: https://platform.claude.com/docs/es/manage-claude/plugins-api
description: "Inventaría y administra los plugins de tu organización de Claude Enterprise: sube plugins y versiones, elige la versión que se sirve a los miembros, controla quién puede usar cada plugin, descarga los archivos de los plugins para revisarlos y valida un marketplace antes de conectarlo."
---

La API de plugins te permite inventariar cada "plugin" (complemento) de tu organización de Claude Enterprise, publicar plugins y nuevas versiones desde tus propios pipelines, elegir qué versión se sirve a los miembros, controlar quién puede usar cada plugin, descargar los archivos de los plugins para revisarlos y comprobar un "marketplace" (mercado) de Git antes de conectarlo.

Para los informes de *uso* de plugins (qué plugins y "skills" (habilidades) usan los miembros, y con qué frecuencia), consulta [API de análisis](https://platform.claude.com/docs/es/manage-claude/analytics-api).

<Check>
  **Se requiere una clave de API de administrador con alcance**

  Estos "endpoints" (puntos de conexión) requieren una clave de API de administrador con el "scope" (alcance) `read:plugins` (para los endpoints `GET`, incluidas las descargas de archivos comprimidos) o el alcance `write:plugins` (para los endpoints `POST` y `DELETE`, excepto la validación de marketplaces, que permite cualquiera de los dos alcances); [Alcances](https://platform.claude.com/docs/es/manage-claude/plugins-api#scopes) tiene los detalles, incluidos otros dos alcances de lectura que también funcionan. Consulta [Crear una clave de API de administrador](https://platform.claude.com/docs/es/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization) para saber dónde la crea tu propietario principal. Pasa la clave en el encabezado `x-api-key` en cada solicitud, junto con el encabezado [`anthropic-version`](https://platform.claude.com/docs/es/api/versioning) y el encabezado beta que se muestra en la siguiente nota.
</Check>

<Note>
  La API de plugins está en **beta** y solo está disponible para organizaciones de Claude Enterprise. No está disponible para organizaciones de Claude Platform (Claude Console) ni para organizaciones que tengan habilitada la preparación para HIPAA.

  Cada solicitud debe incluir el [encabezado beta](https://platform.claude.com/docs/es/api/beta-headers) `anthropic-beta: ce-plugins-2026-09-01` (los SDK y la CLI `ant` lo envían por ti). Una solicitud sin él devuelve `404`, exactamente como si el endpoint no existiera.
</Note>

## Endpoints

La API expone 18 endpoints en cinco recursos:

| Recurso                                                                                                                                                                                                               | Endpoints                                                                                                                                                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Plugins**: lista todos los plugins de la organización, sube uno nuevo, consulta uno, elige la versión que se sirve a los miembros (revertir o promover), elimina uno                                                | `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}`                                                                                              |
| **Versiones de plugins**: lista el historial de versiones de un plugin, sube una nueva versión, consulta una, descarga los archivos de una versión                                                                    | `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`                                                           |
| **Configuración de instalación**: lee quién puede usar un plugin propiedad de la organización, establécela para toda la organización o para un grupo, elimina cualquiera de las dos configuraciones                   | `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}`                                                                                     |
| **Uso compartido**: lee con quién ha compartido un miembro su propio plugin (solo lectura)                                                                                                                            | `GET /v1/organizations/plugins/{plugin_id}/shares`                                                                                                                                                                                                                                                                        |
| **Marketplaces de plugins**: encuentra el ID de un marketplace, consulta uno, establece la configuración de instalación predeterminada para sus plugins, comprueba el contenido de un marketplace antes de conectarlo | `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` |

Esta versión no incluye skills independientes (skills que un miembro escribe en el editor de skills o sube como una sola skill en claude.ai). No aparecen en el inventario y no se pueden crear aquí. Los plugins que publica Anthropic tampoco se inventarían; su uso se informa mediante las [API de análisis](https://platform.claude.com/docs/es/manage-claude/analytics-api). Los marketplaces se crean, se conectan a repositorios y se eliminan en claude.ai, no a través de esta API.

## Requisitos previos

* Tu organización debe tener un plan Claude Enterprise.
* Tu propietario principal crea una clave de API de administrador con el alcance `read:plugins`, el alcance `write:plugins` o ambos en [claude.ai > Configuración de la organización > API](https://claude.ai/admin-settings/api-access). Consulta [Crear una clave de API de administrador](https://platform.claude.com/docs/es/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization).
* Cada solicitud lleva tres encabezados: `x-api-key`, `anthropic-version: 2023-06-01` y `anthropic-beta: ce-plugins-2026-09-01`.

Los SDK de Python, TypeScript, C#, Go, Java, PHP y Ruby exponen estos endpoints en `client.beta.organization` (csharp, go: `client.Beta.Organization`; java: `client.beta().organization()`; php: `$client->beta->organization`), y la [CLI `ant`](https://platform.claude.com/docs/es/cli-sdks-libraries/cli/quickstart) en `ant beta:organization`; envían los encabezados `anthropic-version` y `anthropic-beta` por ti. Los ejemplos de esta página usan el cliente predeterminado de cada SDK, que, al igual que la CLI, lee la clave de API de administrador de la variable de entorno `ANTHROPIC_API_KEY`; los ejemplos de curl leen la clave de la misma variable y la pasan en el encabezado `x-api-key`. Cuando un SDK o la CLI obtiene más páginas por ti, `limit` establece el tamaño de página, no el total (consulta [Paginación](https://platform.claude.com/docs/es/manage-claude/plugins-api#pagination)).

Las claves de API pertenecen a la organización y siguen funcionando después de que la persona que las creó se va. No las compartas ni las incluyas en el control de código fuente.

## Inicio rápido

Enumera los plugins de los marketplaces propios de tu organización, del más reciente al más antiguo:

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

  # Obtiene automáticamente más páginas según sea necesario.
  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,
  );

  // Solo esta página; para la siguiente, vuelve a llamar a list() con 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"
}
```

En este ejemplo, el plugin está fijado a una versión anterior: una versión más reciente (`latest_version_id`) está almacenada, pero aún no se sirve.

## Alcances

| Alcance                    | Otorga                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `read:plugins`             | Todos los endpoints `GET` de esta página, incluidas las descargas de archivos comprimidos, además de la validación de marketplaces.                                                                                                                                                                                                                                                                                                                                      |
| `write:plugins`            | Todos los endpoints `POST` y `DELETE` de esta página: crear un plugin, crear una versión, cambiar la versión servida, eliminar un plugin, establecer y eliminar configuraciones de instalación y establecer el valor predeterminado de un marketplace, además de la validación de marketplaces. No otorga lecturas.                                                                                                                                                      |
| `read:org_audit`           | Un alcance de solo lectura para integraciones de auditoría de seguridad: todos los endpoints `GET` de esta página, incluidas las descargas de archivos comprimidos, además de los endpoints de lectura de [administración de usuarios](https://platform.claude.com/docs/es/manage-claude/user-management) y de la [API de cumplimiento](https://platform.claude.com/docs/es/manage-claude/compliance-api). No otorga la validación de marketplaces ni ninguna escritura. |
| `read:compliance_org_data` | El alcance de la API de cumplimiento para los metadatos de la organización (nombres, tipos, roles y grupos) y la configuración efectiva. Otorga todos los endpoints `GET` de esta página, exactamente como `read:org_audit`, por lo que una clave de acceso de cumplimiento puede leer plugins sin una segunda clave. No otorga la validación de marketplaces ni ninguna escritura.                                                                                      |

Una clave puede tener varios alcances. Una integración que sube un plugin y luego lo vuelve a leer necesita tanto `read:plugins` como `write:plugins`. Siempre que esta página diga que un endpoint requiere el alcance `read:plugins`, una clave con `read:org_audit` o `read:compliance_org_data` también funciona.

### Acceso a los archivos de plugins de los miembros

Cada uno de estos alcances de lectura (`read:plugins`, `read:org_audit` y `read:compliance_org_data`) puede descargar los archivos de los plugins de los marketplaces personales de los miembros, incluidos archivos que la configuración de administración de claude.ai no muestra, y una clave `read:org_audit` o `read:compliance_org_data` vinculada a tu organización matriz puede hacerlo en cualquier organización bajo ella que tenga acceso a esta API, pasando `organization_id` (consulta [Leer otra organización bajo la misma organización matriz](https://platform.claude.com/docs/es/manage-claude/plugins-api#reading-another-organization-under-the-same-parent)). Cada una de estas descargas registra un evento `claude_plugin_archive_accessed` en el [feed de actividad de la API de cumplimiento](https://platform.claude.com/docs/es/manage-claude/compliance-activity-feed), que identifica la clave, el plugin, la versión y el miembro (consulta [Eventos del feed de actividad](https://platform.claude.com/docs/es/manage-claude/plugins-api#activity-feed-events)). Las descargas de plugins propiedad de la organización no se registran.

### Leer otra organización bajo la misma organización matriz

Las claves `read:plugins` y `write:plugins` leen y escriben solo en la organización en la que se crearon. Si tu empresa tiene varias organizaciones de Claude vinculadas bajo una organización matriz, una clave `read:org_audit` o `read:compliance_org_data` que el propietario principal de la organización matriz creó para todas las organizaciones vinculadas (consulta [Crear una clave de API de administrador](https://platform.claude.com/docs/es/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization)) también puede leer cualquiera de ellas que tenga acceso a esta API: pasa el ID de esa organización en el parámetro de consulta `organization_id` en cualquier endpoint `GET` de esta página. El ID es el UUID de la organización que se muestra en la configuración de claude.ai (también se acepta su forma con el prefijo `org_`). Sin el parámetro, la clave lee la organización en la que se creó. Un `404` significa que la organización indicada no está bajo la organización matriz de la clave o que la API no está disponible para ella; un valor que no sea un UUID ni un ID `org_` devuelve `400`. Cualquier otra clave que indique una organización distinta de la suya recibe `404`. Las escrituras no aceptan `organization_id`.

## Conceptos clave

### Plugins y componentes

Un **plugin** es un paquete que amplía Claude para los miembros de tu organización. Contiene cualquier combinación de estos componentes:

| Componente   | Qué es                                                                                                                                 |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| Skill        | Instrucciones y archivos que Claude carga cuando una tarea lo requiere.                                                                |
| Comando      | Un prompt guardado que un miembro ejecuta escribiendo `/` seguido del nombre del comando.                                              |
| Agente       | Un asistente auxiliar con sus propias instrucciones, al que Claude puede delegar parte de una tarea.                                   |
| Hook         | Un comando que se ejecuta automáticamente cuando ocurre un evento en una sesión, por ejemplo, antes de que Claude use una herramienta. |
| Servidor MCP | Una conexión de Claude a herramientas y datos de otro sistema (Model Context Protocol).                                                |
| CLI          | Un programa de línea de comandos que el plugin permite que Claude ejecute.                                                             |

Cada plugin tiene un manifiesto en `.claude-plugin/plugin.json`. El `name` del manifiesto se convierte en el `name` del plugin: un identificador en minúsculas que es único dentro de su marketplace.

### Marketplaces

Un **marketplace** es un contenedor de plugins. Cada marketplace tiene un propietario y un origen.

* **Propietario.** La organización es propietaria de sus marketplaces. Cada miembro también puede tener marketplaces personales.
* **Origen.** `manual` significa que los plugins se suben, en claude.ai o, para un marketplace de la organización, a través de esta API. `github`, `gitlab` y `public_git` significan que los plugins se sincronizan desde un repositorio de Git que conectó el propietario. No se puede subir nada a un marketplace sincronizado, y esta API no puede eliminar sus plugins, porque la siguiente sincronización desharía cualquiera de los dos cambios. En su lugar, cambia el repositorio.

El **marketplace de biblioteca** de tu organización es el marketplace `manual` propiedad de la organización al que van las subidas cuando no indicas un marketplace. Se crea la primera vez que se sube algo a él.

### Plugins propiedad de la organización y propiedad de miembros

El `owner.type` de un plugin indica en qué marketplace se encuentra:

* `organization`: puedes administrarlo a través de esta API, excepto que un plugin de un marketplace sincronizado desde Git no puede recibir subidas ni eliminarse aquí.
* `user`: se encuentra en el marketplace personal de un miembro. Puedes leer sus detalles y descargar sus archivos, y eliminarlo si su marketplace es `manual`. Subir versiones y elegir la versión servida devuelven `403`. El uso compartido lo administra solo el miembro, en claude.ai.

Quitar a un miembro de la organización no elimina sus plugins. Permanecen en el inventario bajo el `user_id` del miembro, y el filtro `owner_user_id` todavía los encuentra, de modo que puedes revisar y eliminar el contenido de un miembro que se fue. Se eliminan del inventario cuando se elimina la cuenta del miembro.

### Versiones y la versión servida

Cada subida crea una nueva **versión** inmutable, ya provenga de esta API, de claude.ai o de una sincronización de Git. Un plugin tiene dos punteros a sus versiones:

* `latest_version_id`: la versión más reciente.
* `served_version_id`: la versión que se sirve a los miembros.

De forma predeterminada, `served_version_pinned` es `false`: la versión servida normalmente sigue a la más reciente. Cuando el análisis de contenido está activado, una versión guardada en claude.ai podría **esperar** su análisis de contenido: se almacena pero no se sirve de inmediato. Esta página usa "esperar" solo para una versión guardada en claude.ai, no para una que un miembro o un administrador publica en un plugin. Mientras el análisis está activado, una versión en espera se sirve solo después de que su análisis se complete con `pass` o `warn`. Mientras una versión espera, `served_version_id` indica una versión anterior a `latest_version_id`. No sondees hasta que los dos ID coincidan: podrían seguir siendo diferentes, por ejemplo, cuando el análisis falla.

Elegir una versión con `POST /v1/organizations/plugins/{plugin_id}` **fija** el plugin (`served_version_pinned: true`). Lo mismo ocurre cuando un administrador elige una versión en claude.ai o acepta la solicitud de un miembro para publicar en el plugin. A partir de entonces, las nuevas subidas se almacenan y hacen avanzar `latest_version_id`, pero los miembros conservan la versión fijada hasta que apuntes `served_version_id` a otra. Un plugin cuyos dos punteros difieren tiene una versión almacenada que no se está sirviendo.

Esto permite que un pipeline de lanzamiento suba cada compilación, la pruebe y luego la promueva. Para que tu pipeline decida cuándo se sirve cada compilación, fija el plugin una vez estableciendo `served_version_id` en su versión actual; a partir de entonces, promueve cada compilación que quieras servir. Con el análisis de contenido activado, esa primera fijación devuelve `409 scan_pending` hasta que se complete el análisis de la versión actual, y `400 scan_failed` si el análisis se completó con `fail` o `unknown`, o produjo un error (`warn` se acepta). Actualmente, un plugin fijado no se puede desfijar, ni aquí ni en claude.ai.

Para revertir, establece `served_version_id` en una versión anterior. Avanza de la misma manera.

Estas reglas describen los plugins propiedad de la organización. La versión servida de un plugin propiedad de un miembro la controla su propietario en claude.ai.

### Configuración de instalación

La **configuración de instalación** decide quién puede usar un plugin propiedad de la organización. Cada configuración tiene uno de cuatro valores, que se incluyen en los campos llamados `installation_preference` (y, en los objetos de plugin y marketplace, `organization_installation_preference` y `default_installation_preference`):

| Valor           | Los miembros ven                               |
| --------------- | ---------------------------------------------- |
| `required`      | El plugin está instalado y no se puede quitar. |
| `auto_install`  | El plugin está instalado y se puede quitar.    |
| `available`     | El plugin se puede instalar a petición.        |
| `not_available` | El plugin está oculto.                         |

Un plugin puede tener una configuración para toda la organización y una configuración por grupo (los grupos de control de acceso basado en roles que se administran en [Administración de usuarios](https://platform.claude.com/docs/es/manage-claude/user-management#groups)). Un miembro obtiene un valor según estas reglas:

1. El valor para toda la organización es la configuración propia del plugin para toda la organización si tiene una; de lo contrario, el valor predeterminado de su marketplace; de lo contrario, `not_available`. El plugin informa este valor en `organization_installation_preference`, con `organization_installation_preference_inherited: true` mientras proviene del valor predeterminado del marketplace.
2. Un miembro que no pertenece a ningún grupo con una configuración para el plugin obtiene el valor para toda la organización.
3. Un miembro que pertenece a uno o más grupos con una configuración obtiene, en su lugar, la más permisiva de las configuraciones de esos grupos, en el orden `required`, `auto_install`, `available`, `not_available`.

La configuración de un grupo reemplaza el valor para toda la organización para sus miembros; no se suma a él. Por ejemplo, si el valor para toda la organización es `required` y el grupo Pilot tiene `available`, los miembros de Pilot obtienen `available`. Cuando pases un plugin de un grupo piloto a toda la organización, establece el valor para toda la organización y luego elimina la configuración del grupo. Establecer el valor para toda la organización hace que el plugin deje de heredar el valor predeterminado de su marketplace; [eliminar la configuración para toda la organización](https://platform.claude.com/docs/es/manage-claude/plugins-api#remove-an-installation-setting) devuelve el plugin a ese valor predeterminado.

Un plugin creado a través de esta API comienza sin configuraciones propias, por lo que hereda el valor predeterminado de su marketplace: `not_available`, a menos que alguien haya establecido un valor predeterminado. Eliminar un grupo elimina sus configuraciones de todos los plugins.

### Uso compartido

El **uso compartido** decide quién puede usar un plugin propiedad de un miembro. El propietario lo comparte en claude.ai con todos los miembros, con un grupo o con miembros específicos. Esta API enumera los elementos compartidos, pero no puede cambiarlos.

Si tu organización desactivó un tipo de uso compartido en su configuración de claude.ai, los elementos compartidos de ese tipo siguen apareciendo en la lista, pero no dan acceso a nadie mientras esa configuración esté desactivada; la lista en sí no muestra si lo está.

### Análisis de contenido

El análisis de contenido es una configuración de la organización en claude.ai. Cuando está activado, las versiones recién almacenadas se analizan (claude.ai exime a algunas) y el resultado se informa en `content_scan`; una versión que no se analizó, por ejemplo, una almacenada antes de que se activara el análisis, tiene `content_scan: null`. El análisis no se ofrece a organizaciones que usan claves de cifrado administradas por el cliente o retención de datos cero.

Mientras el análisis está activado, a los miembros se les sirve un plugin solo cuando el análisis de su versión servida está `completed` con `pass` o `warn`. Mientras el análisis se ejecuta, o después de que falla, produce un error o no llega a un veredicto, el plugin se retiene a los miembros, y no se sirve una versión anterior en su lugar. Una versión que nunca se analizó (`content_scan: null`) se sirve normalmente.

Una versión que subes a través de esta API nunca espera su análisis de contenido. Cuando se convierte en la versión servida, los miembros pierden el plugin hasta que su análisis se aprueba, y siguen sin él si el análisis falla. Si los miembros deben conservar la versión actual mientras se analiza una nueva, fija primero el plugin (consulta [Versiones y la versión servida](https://platform.claude.com/docs/es/manage-claude/plugins-api#versions-and-the-served-version)).

Mientras una versión guardada en claude.ai espera su análisis, la versión servida no cambia. Cuando tu subida por API se convierte en la versión servida, cualquier espera termina: la versión en espera se sirve solo si alguien la elige. Para ver el análisis de una versión en espera, lee la versión (consulta [Listar las versiones de un plugin](https://platform.claude.com/docs/es/manage-claude/plugins-api#list-a-plugins-versions)).

Después de una subida, `content_scan.status` es `processing` y el veredicto llega de forma asíncrona. Lee la versión para verlo; el objeto de plugin muestra solo el análisis de su versión servida. Cambiar la versión servida a una versión cuyo análisis aún se está ejecutando devuelve `409 scan_pending`; a una cuyo análisis falló, `400 scan_failed`.

### Alcance de acción

`reach` resume, en un solo valor, hasta dónde llega una versión en los equipos de los miembros y más allá:

| Valor        | Significado                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `remote`     | Declara un servidor MCP o una CLI, independientemente de lo que más declare.                                                                                                                                                                                                                                                                                                                                                                                                 |
| `privileged` | No declara ningún servidor MCP ni CLI, pero declara un hook, un monitor (un comando en segundo plano que sigue ejecutándose durante una sesión), un servidor LSP (Language Server Protocol) o configuraciones que el plugin aplica a la aplicación del miembro, o contiene una skill, un comando o cualquier otro archivo Markdown cuyo frontmatter aprueba previamente herramientas (`allowed-tools`). Estos se ejecutan, o surten efecto, en el propio equipo del miembro. |
| `contained`  | No declara ningún servidor MCP, CLI, hook, monitor, servidor LSP ni configuración de la aplicación, y ninguno de sus archivos Markdown aprueba previamente herramientas (por ejemplo, un plugin que contiene solo skills, comandos y agentes, ninguno con `allowed-tools`).                                                                                                                                                                                                  |

`reach` cuenta todo lo que declara la versión, incluidos monitores, servidores LSP y configuraciones de la aplicación, que `components` no lista, por lo que una versión con una lista `components` vacía aún puede ser `privileged`. Es `null` para una versión almacenada antes de que se registraran los componentes, y para una versión cuyo alcance de acción no se pudo determinar porque no se pudo leer el `SKILL.md` de una de sus skills o uno de sus archivos de comandos; trata `null` como sin clasificar.

### Requisitos de subida

Las subidas siguen las mismas reglas que las subidas de plugins en claude.ai, por lo que se aceptan los mismos archivos comprimidos en ambos lugares.

* La subida es un único archivo comprimido `.zip` o `.plugin`, o un conjunto de archivos individuales. Un archivo comprimido puede envolver todo en una carpeta de nivel superior.
* Debe contener exactamente un manifiesto, en `.claude-plugin/plugin.json`, que debe declarar un `name`. Se rechaza un `SKILL.md` suelto sin manifiesto.
* Un `SKILL.md` de nivel superior cuyo frontmatter declara componentes de plugin se combina con el manifiesto; `plugin.json` prevalece dondequiera que ambos establezcan un valor.
* `name` puede contener letras minúsculas (de cualquier alfabeto), dígitos y guiones, hasta 64 caracteres. Se rechazan las letras mayúsculas, los espacios, los guiones bajos y otros signos de puntuación.
* `displayName` tiene como máximo 64 caracteres y `description` como máximo 500.
* Cada `SKILL.md` necesita un frontmatter YAML válido con `name` y `description`, sin que ninguno contenga etiquetas XML como `<example>`. Dos skills, o dos comandos, no pueden compartir un nombre.
* Ningún archivo puede estar en un directorio `bin/` de nivel superior.
* No se permiten archivos `.zip` anidados. Se permiten servidores MCP empaquetados (`.mcpb`, `.dxt`).
* Las rutas de archivo deben ser relativas, no contener `..` y usar solo letras, dígitos, espacios y `_ . - / ( ) ,`.
* El cuerpo de la solicitud y el archivo comprimido una vez descomprimido tienen cada uno como máximo 200 MB; un cuerpo de solicitud que supera el límite devuelve `413` (`request_too_large`) en lugar de `400`. Una subida tiene como máximo 5,000 archivos, una profundidad de ruta de 12, rutas de 472 caracteres y nombres de archivo o carpeta de 255 caracteres.
* Los archivos ZIP deben usar compresión DEFLATE o STORE, y no pueden estar cifrados ni contener enlaces simbólicos.
* Un marketplace contiene como máximo 500 elementos, contando sus plugins y cualquier skill independiente que los miembros guarden en él. Este límite y el límite de 5,000 archivos son valores actuales que podrían aumentarse.

## Flujos de trabajo de ejemplo

### Publicar cada compilación desde un pipeline de lanzamiento

Sube cada compilación etiquetada desde CI y deja que el pipeline decida cuándo se sirve una compilación.

1. Encuentra el marketplace al que vas a subir con `GET /v1/organizations/plugin_marketplaces?owner_type=organization`, u omite `marketplace_id` para usar el marketplace de biblioteca.
2. En el primer lanzamiento, [crea el plugin](https://platform.claude.com/docs/es/manage-claude/plugins-api#create-a-plugin) con `POST /v1/organizations/plugins`. En cada lanzamiento posterior, registra el `latest_version_id` del plugin y luego [sube una versión](https://platform.claude.com/docs/es/manage-claude/plugins-api#create-a-version) con `POST /v1/organizations/plugins/{plugin_id}/versions`. Si se pierde la respuesta de la subida, lee el plugin y vuelve a intentarlo solo si `latest_version_id` no cambió (consulta [Reintentar subidas](https://platform.claude.com/docs/es/manage-claude/plugins-api#retrying-uploads)).
3. Para mantener a los miembros en la versión actual mientras se comprueba cada nueva compilación, fija el plugin una vez estableciendo `served_version_id` en su versión actual. A partir de entonces, cada subida se almacena sin servirse, y la fijación no se puede deshacer: cada compilación que quieras servir necesita el paso 5.
4. Cuando el escaneo de contenido esté activado, consulta periódicamente `GET /v1/organizations/plugins/{plugin_id}/versions/{version}` hasta que `content_scan.status` ya no sea `processing`, y promueve solo cuando sea `completed` con `pass` o `warn`.
5. [Promueve la compilación](https://platform.claude.com/docs/es/manage-claude/plugins-api#change-the-served-version) con `POST /v1/organizations/plugins/{plugin_id}` y `{"served_version_id": "<the new version's ID>"}`. Para revertir, envía el ID de la versión anterior de la misma manera.

### Implementar un plugin para un grupo piloto y luego para todos

1. Busca el ID del grupo piloto con `GET /v1/organizations/rbac_groups`. Esa llamada necesita el alcance `read:rbac_groups`, que requiere una clave creada para todas las organizaciones vinculadas (consulta [Administración de usuarios](https://platform.claude.com/docs/es/manage-claude/user-management#groups)). Los siguientes pasos necesitan `write:plugins`, que actúa solo sobre la organización en la que se creó su clave, por lo que en una empresa con varias organizaciones vinculadas, crea esta clave en la organización que contiene el plugin y dale ambos alcances, o usa una segunda clave creada allí para esos pasos.

2. [Dale al grupo su propia configuración](https://platform.claude.com/docs/es/manage-claude/plugins-api#set-an-installation-setting), por ejemplo `auto_install`, con `POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}`, donde `{target}` es el ID `rbac_group_` del grupo, mientras el valor para toda la organización sigue siendo `not_available`. Solo los miembros del grupo obtienen el plugin.

3. Cuando termine el piloto, establece el valor para toda la organización con la siguiente llamada y luego elimina la configuración del grupo para que el grupo vuelva a seguir a la organización. Establecer el valor para toda la organización hace que el plugin deje de heredar el valor predeterminado de su marketplace; [eliminar la configuración para toda la organización](https://platform.claude.com/docs/es/manage-claude/plugins-api#remove-an-installation-setting) más adelante devuelve el plugin a ese valor predeterminado.

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

   Luego elimina la configuración del grupo con `DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}`, donde `{target}` es el ID del grupo. La configuración de un grupo reemplaza el valor para toda la organización para sus miembros en lugar de sumarse a él, por lo que una configuración de grupo sobrante de `available` mantendría a esos miembros en `available`.

### Mantener sincronizado un inventario de seguridad

Ejecuta un trabajo nocturno que marque los plugins que llegan más allá de la sesión del miembro o que no superan su análisis de contenido.

1. Recorre las páginas de [`GET /v1/organizations/plugins?limit=100`](https://platform.claude.com/docs/es/manage-claude/plugins-api#list-plugins) hasta que `next_page` sea `null` (consulta [Paginación](https://platform.claude.com/docs/es/manage-claude/plugins-api#pagination)). Lee el `reach` y el `content_scan` de cada plugin de esa lista en cada ejecución: un veredicto de análisis que llega más tarde no modifica `updated_at`. `updated_at` normalmente te indica qué plugins tienen contenido nuevo o una nueva versión servida desde la última ejecución (vale la pena una nueva descarga del archivo comprimido). Una versión en espera (consulta [Versiones y la versión servida](https://platform.claude.com/docs/es/manage-claude/plugins-api#versions-and-the-served-version)) modifica `updated_at` cuando se convierte en la versión servida, no necesariamente cuando se almacena. Para detectarla, compara `latest_version_id` con el valor de tu última ejecución. Volver a listar todo es también lo que detecta las eliminaciones, porque un plugin eliminado por una sincronización de Git o por la eliminación de una cuenta desaparece sin un evento.
2. Marca cada plugin cuyo `reach` sea `remote` (declara un servidor MCP o una CLI), o cuyo `content_scan.assessment` sea `fail` o `unknown`. Estos campos describen la versión servida. Para comprobar también una versión más reciente que no se sirve, lista las versiones del plugin cuando `latest_version_id` difiera de `served_version_id` (consulta [Listar las versiones de un plugin](https://platform.claude.com/docs/es/manage-claude/plugins-api#list-a-plugins-versions)).
3. Para cada plugin marcado, descarga el archivo comprimido de la versión servida para revisarlo con `GET /v1/organizations/plugins/{plugin_id}/versions/{served_version_id}/content` (consulta [Descargar los archivos de una versión](https://platform.claude.com/docs/es/manage-claude/plugins-api#download-a-versions-files)). Descarga también, por su ID, cualquier versión no servida que cumpla la prueba del paso 2.
4. Para retirar un plugin a los miembros mientras lo revisas, consulta [Eliminar un plugin](https://platform.claude.com/docs/es/manage-claude/plugins-api#delete-a-plugin) para ver las opciones reversible (propiedad de la organización) y permanente.

## Plugins

El objeto de plugin describe un plugin de uno de los marketplaces de tu organización o del marketplace personal de un miembro (la respuesta del [Inicio rápido](https://platform.claude.com/docs/es/manage-claude/plugins-api#quick-start) muestra uno completo). Sus campos `display_name`, `description`, `manifest_version`, `content_scan`, `components` y `reach` describen su versión **servida**, de modo que una sola llamada de listado muestra lo que se está sirviendo a los miembros.

| Campo                                                                                    | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                                                                     | Con el prefijo `plugin_`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `name`                                                                                   | Del manifiesto. Único dentro de su marketplace, no en toda la organización. Fijo para un plugin propiedad de la organización; cambia si un miembro cambia el nombre de su propio plugin en claude.ai.                                                                                                                                                                                                                                                                                                                                                                                                               |
| `display_name`, `description`, `manifest_version`                                        | Los valores `displayName`, `description` y `version` del manifiesto de la versión servida; cada uno es `null` cuando el manifiesto no declara ninguno. `manifest_version` se normaliza para su visualización: se elimina una `v` o `V` inicial, por lo que un `version` de manifiesto de `"v1.4.0"` se devuelve como `"1.4.0"`. También es `null` para un valor que no parece un número de versión, como `"latest"`, y para una versión de plugin creada antes de que claude.ai comenzara a registrar este campo en agosto de 2026. Una subida nunca se rechaza por su `version`, y `manifest_version` no es único. |
| `served_version_id`, `latest_version_id`                                                 | Con el prefijo `pluginver_`: la versión que se sirve a los miembros y la versión más reciente. Consulta [Versiones y la versión servida](https://platform.claude.com/docs/es/manage-claude/plugins-api#versions-and-the-served-version).                                                                                                                                                                                                                                                                                                                                                                            |
| `served_version_pinned`                                                                  | `false` hasta que el plugin se fija (consulta [Versiones y la versión servida](https://platform.claude.com/docs/es/manage-claude/plugins-api#versions-and-the-served-version)); `true` a partir de entonces.                                                                                                                                                                                                                                                                                                                                                                                                        |
| `owner`                                                                                  | `{"type": "organization"}`, o `{"type": "user", "user_id": "user_..."}` para el marketplace personal de un miembro.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `marketplace_id`                                                                         | Con el prefijo `marketplace_`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `created_by`                                                                             | Quién creó el plugin: `{"type": "user_actor", "user_id": "user_...", "email_address": "..."}` para una persona en claude.ai (`email_address` puede ser `null`), o `{"type": "api_actor", "api_key_id": "apikey_..."}` para una clave de API. Pueden aparecer otros tipos de actor. `null` cuando no se registra ningún creador, como en los plugins sincronizados desde Git.                                                                                                                                                                                                                                        |
| `organization_installation_preference`, `organization_installation_preference_inherited` | Propiedad de la organización: el valor para toda la organización y si proviene del valor predeterminado del marketplace (consulta [Configuración de instalación](https://platform.claude.com/docs/es/manage-claude/plugins-api#installation-settings)). Propiedad de un miembro: ambos `null`.                                                                                                                                                                                                                                                                                                                      |
| `content_scan`                                                                           | El resultado del análisis de la versión servida, un objeto con `status`, `assessment` y `reason` (descritos después de esta tabla). `null` cuando nunca se analizó.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `components`                                                                             | Los componentes de la versión servida, cada uno `{"type", "name", "description"}` con `type` igual a `skill`, `mcp_server`, `command`, `agent`, `hook` o `cli`, listados en ese orden de tipo y luego por nombre. Para un servidor MCP, `name` es su clave en el manifiesto; para un hook, el evento en el que se ejecuta; para una CLI, el nombre del ejecutable. `description` siempre es `null` para servidores MCP, hooks y CLI. `null` cuando no se registra.                                                                                                                                                  |
| `reach`                                                                                  | `contained`, `privileged` o `remote`. Consulta [Alcance de acción](https://platform.claude.com/docs/es/manage-claude/plugins-api#reach).                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `updated_at`                                                                             | Cambia cuando cambia la versión servida, cuando el plugin se fija y, normalmente, cuando se almacena una nueva versión. Una versión en espera (consulta [Versiones y la versión servida](https://platform.claude.com/docs/es/manage-claude/plugins-api#versions-and-the-served-version)) lo cambia cuando se convierte en la versión servida, no necesariamente cuando se almacena. No cambia por configuraciones de instalación, uso compartido ni nuevos resultados de análisis.                                                                                                                                  |

El objeto `content_scan`:

| Campo        | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`     | `processing` mientras se ejecuta el análisis, `completed` cuando terminó, o `errored` cuando no pudo terminar (u, ocasionalmente, cuando su resultado no se pudo leer para esta respuesta, en cuyo caso una lectura posterior podría informarlo). A los miembros no se les sirve una versión cuyo análisis esté en `processing` o `errored`; volver a subir el contenido como una nueva versión obtiene un análisis nuevo. |
| `assessment` | Se establece cuando `status` es `completed`: `pass` (no se encontró nada), `warn` (se encontró algo que no bloquea el uso), `fail` (se encontró algo que bloquea el uso) o `unknown` (sin veredicto). De lo contrario, `null`.                                                                                                                                                                                             |
| `reason`     | Para `warn` y `fail`, la preocupación principal, de la siguiente lista. De lo contrario, `null`, y también `null` en un análisis más antiguo anterior al registro de motivos.                                                                                                                                                                                                                                              |

<Accordion title="Valores de reason del análisis de contenido">
  | `reason`                          | Significado                                                                                                                                      |
  | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
  | `covert-usage-telemetry`          | Indica a Claude que envíe información sobre el miembro o su uso a una dirección externa sin decírselo.                                           |
  | `undisclosed-data-destination`    | Envía archivos, correos electrónicos, documentos u otro contenido a un destino externo fijo que no se muestra al miembro y que este no controla. |
  | `remote-code-instruction-loader`  | Indica a Claude que descargue y ejecute, o siga instrucciones de, contenido externo que puede cambiar después de instalar el plugin.             |
  | `credential-exposure`             | Contiene credenciales activas, o recopila credenciales o tokens del entorno del miembro.                                                         |
  | `guardrail-tampering`             | Debilita las salvaguardas del miembro, por ejemplo, aprobando previamente todas las solicitudes de permiso.                                      |
  | `system-prompt-spoofing`          | Imita o intenta reemplazar las instrucciones del sistema de Claude.                                                                              |
  | `covert-record-tampering`         | Cambia, oculta o elimina discretamente información que el miembro vería de otro modo.                                                            |
  | `covert-behavior-override`        | Cambia el comportamiento de Claude más allá del propósito del plugin y oculta el cambio al miembro.                                              |
  | `hidden-code-execution`           | Ejecuta código incluido mientras indica a Claude que no revele lo que hace.                                                                      |
  | `undisclosed-promotion-injection` | Inserta contenido promocional no revelado en la salida de Claude.                                                                                |
  | `hidden-identity-gate`            | Cambia o detiene su comportamiento según la cuenta que lo ejecuta, sin decir por qué.                                                            |
  | `destructive-persistence`         | Puede eliminar o dañar los archivos del miembro, o instalar programas que permanecen después del plugin.                                         |
  | `unanalyzable-binary`             | Incluye un programa compilado o ilegible, por lo que el análisis no pudo verificar lo que hace.                                                  |
  | `other`                           | Cualquier otra preocupación, incluida una más reciente que esta lista.                                                                           |
</Accordion>

Un `plugin_id` que carece del prefijo `plugin_` devuelve `400`. Un `plugin_id` que lleva el prefijo pero no se resuelve, pertenece a otra organización o hace referencia a una skill independiente devuelve `404`.

### Enumerar plugins

`GET /v1/organizations/plugins` enumera todos los plugins de tu organización, en los marketplaces de la organización y en los marketplaces personales de los miembros, ordenados por `created_at` de forma descendente. Filtra por `owner_type` (`organization` o `user`), `owner_user_id` (con el prefijo `user_`; los plugins de un miembro, incluso después de que el miembro deja la organización), `marketplace_id` y `created_at[gte]`, `created_at[gt]`, `created_at[lte]`, `created_at[lt]` (marcas de tiempo RFC 3339). Los filtros se combinan con AND. Un `marketplace_id` o `owner_user_id` que no coincide con nada en tu organización devuelve una página vacía, no un error. La respuesta tiene la forma que se muestra en [Inicio rápido](https://platform.claude.com/docs/es/manage-claude/plugins-api#quick-start). Requiere el alcance `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)

  # Obtiene automáticamente más páginas según sea necesario.
  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,
  );

  // Solo esta página; para la siguiente, vuelve a llamar a list() con 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>

### Crear un plugin

`POST /v1/organizations/plugins` crea un plugin propiedad de la organización y su primera versión en una sola llamada; esa versión se convierte en la "served version" (versión servida). El cuerpo es `multipart/form-data`: `files[]` es un único archivo comprimido `.zip` o `.plugin`, o bien una parte por archivo, donde el nombre de archivo de cada parte es la ruta del archivo dentro del plugin (por ejemplo, `.claude-plugin/plugin.json`). Los campos opcionales son `marketplace_id` y `release_notes`. `marketplace_id` es un marketplace `manual` propiedad de la organización; si lo omites, se usa tu marketplace de biblioteca, que se crea la primera vez que se usa. `release_notes` admite hasta 5,000 caracteres, se muestra en el historial de versiones de claude.ai y se devuelve en la versión. Los campos `name`, `display_name`, `description` y `manifest_version` del plugin provienen del manifiesto cargado, y la carga debe cumplir los [requisitos de carga](https://platform.claude.com/docs/es/manage-claude/plugins-api#upload-requirements). Cuando el "content scanning" (análisis de contenido) está activado, el `content_scan.status` de la respuesta es `processing` y el veredicto llega de forma asíncrona. Devuelve el plugin. Requiere el ámbito `write:plugins`.

Carga un archivo comprimido:

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

      // Construye la parte `files[]` manualmente para que el archivo se envíe con su nombre,
      // que la carga requiere.
      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"
}
```

Carga archivos individuales en un marketplace específico. Adjunta cada archivo con su ruta dentro del plugin: en el ejemplo de cURL, es el sufijo `;filename=`; en los ejemplos de SDK, son los argumentos de nombre de archivo. Si envías un archivo solo con su nombre base, no se encontrará el manifiesto. Los SDK de TypeScript y Java y la CLI `ant` aún no pueden adjuntar archivos con una ruta, así que esos ejemplos cargan el plugin en el marketplace como un único archivo comprimido:

<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
  # La CLI envía cada archivo solo con su nombre base,
  # así que sube el plugin como un único archivo comprimido.
  ant beta:organization:plugins create \
    --file dist/sales-toolkit.zip \
    --marketplace-id marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r
  ```

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

  # Una tupla (filename, file) conserva la ruta de cada archivo dentro del plugin;
  # un objeto de archivo simple se enviaría solo con su nombre base.
  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();

  // El SDK de TypeScript envía cada archivo con su nombre base,
  // así que sube el plugin como un solo archivo comprimido.
  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 conserva la ruta de cada archivo dentro del plugin; sin él, un FileStream
  // se envía solo con su nombre base.
  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 conserva la ruta de cada archivo dentro del plugin como nombre de archivo de la parte;
  // un *os.File sin envolver se enviaría con su nombre base y no se encontraría el manifiesto.
  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();

      // Los setters de `files` en PluginCreateParams aceptan un solo nombre de archivo para toda la
      // lista, así que sube el plugin como un único archivo comprimido: una sola
      // parte armada a mano que lleva el nombre del archivo comprimido, como exige la carga.
      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

  # Un FilePart con filename: conserva la ruta de cada archivo dentro del plugin;
  # un Pathname simple se enviaría solo con su nombre base.
  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>

Una creación puede fallar con un `400` si la carga incumple los [requisitos de carga](https://platform.claude.com/docs/es/manage-claude/plugins-api#upload-requirements), o con un `413` si el cuerpo de la solicitud supera los 200 MB. También puede devolver las respuestas compartidas, como un `403` cuando `marketplace_id` es el marketplace personal de un miembro (consulta [Respuestas de error](https://platform.claude.com/docs/es/manage-claude/plugins-api#error-responses)). Además, puede fallar con:

| Estado                     | Causa                                                                                                          | Qué hacer                                                                                                                                                                                                   |
| -------------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 404                        | `marketplace_id` no es un marketplace de tu organización.                                                      | Toma el ID de [Listar marketplaces](https://platform.claude.com/docs/es/manage-claude/plugins-api#list-marketplaces).                                                                                       |
| 400                        | El marketplace se sincroniza desde Git o ya contiene 500 plugins y skills.                                     | Carga en un marketplace `manual` o, en su lugar, modifica el repositorio.                                                                                                                                   |
| 409 `plugin_name_taken`    | El nombre ya está en uso en ese marketplace.                                                                   | Continúa con `details.plugin_id` (carga una versión en él) o cambia el `name` del manifiesto.                                                                                                               |
| 409 `skill_name_taken`     | El plugin va al marketplace de biblioteca y una de sus skills tiene el nombre de una skill de la organización. | Cambia el nombre de la skill o elimina la skill de la organización en claude.ai.                                                                                                                            |
| 409 (sin `error_code`)     | Otra carga con el mismo nombre en el mismo marketplace sigue en curso.                                         | Vuelve a intentarlo en breve.                                                                                                                                                                               |
| 503 `registration_pending` | El plugin se creó, pero su registro no se completó.                                                            | No reenvíes la solicitud; carga los mismos archivos como una versión de `details.plugin_id` (consulta [Reintentar cargas](https://platform.claude.com/docs/es/manage-claude/plugins-api#retrying-uploads)). |

### Obtener un plugin

`GET /v1/organizations/plugins/{plugin_id}` devuelve un plugin. Requiere el ámbito `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>

### Cambiar la versión servida

`POST /v1/organizations/plugins/{plugin_id}` cambia qué versión de un plugin propiedad de la organización se sirve a los miembros. Pasa una versión anterior para revertir, o una más reciente para promover una compilación que se almacenó sin servirse. Esto fija el plugin, y actualmente un plugin fijado no se puede desfijar, ni aquí ni en claude.ai (consulta [Versiones y la versión servida](https://platform.claude.com/docs/es/manage-claude/plugins-api#versions-and-the-served-version)). El único campo actualizable es `served_version_id`, y es obligatorio. El cambio llega a los miembros antes de que se devuelva la respuesta y no crea una versión. Cuando el análisis de contenido está activado, la versión debe ser una que se pueda servir a los miembros (consulta [Análisis de contenido](https://platform.claude.com/docs/es/manage-claude/plugins-api#content-scanning)). Pasar la versión que ya se sirve en un plugin fijado no cambia nada; pasarla en un plugin no fijado lo fija en ella, de modo que las cargas posteriores dejan de servirse automáticamente. Fijar también pone fin a cualquier espera: una versión que estaba esperando su análisis de contenido permanece almacenada y solo se sirve si alguien la elige. Devuelve el plugin. Requiere el ámbito `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"
}
```

Además de las respuestas compartidas (un `403` para un plugin propiedad de un miembro, y `409 scan_pending` o `400 scan_failed` para una versión que no se puede servir a los miembros; consulta [Respuestas de error](https://platform.claude.com/docs/es/manage-claude/plugins-api#error-responses)), la solicitud puede fallar con:

| Estado                 | Causa                                                                                                                                                  | Qué hacer                                                                                                                                 |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 400                    | El cuerpo omite `served_version_id`, lo establece en `null` o contiene cualquier otro campo; o el valor carece del prefijo `pluginver_` o es `latest`. | Envía exactamente `{"served_version_id": "pluginver_…"}`.                                                                                 |
| 404                    | `served_version_id` no es una versión de este plugin.                                                                                                  | Toma el ID de [Listar las versiones de un plugin](https://platform.claude.com/docs/es/manage-claude/plugins-api#list-a-plugins-versions). |
| 409 (sin `error_code`) | Una carga a este plugin u otro cambio de versión servida todavía está en curso.                                                                        | Vuelve a intentarlo en breve.                                                                                                             |
| 409 `skill_name_taken` | El plugin está en el marketplace de biblioteca y la versión tiene una skill cuyo nombre ahora usa una skill de la organización.                        | Elige otra versión, o cambia el nombre de una de las skills.                                                                              |

### Eliminar un plugin

`DELETE /v1/organizations/plugins/{plugin_id}` elimina permanentemente un plugin y todas las versiones que contiene, tal como lo hace la eliminación de un administrador en claude.ai. Funciona con cualquier plugin en un marketplace `manual`, incluido el plugin de un miembro, incluso si ese miembro ya abandonó la organización. Cuando la eliminación termina, el plugin, sus versiones y sus archivos desaparecen de todas las lecturas, y ya no se sirve a los miembros. La configuración de instalación de un plugin propiedad de la organización se elimina con él; los elementos compartidos de un plugin propiedad de un miembro se retiran, y también desaparece para su propietario. Un plugin en un marketplace sincronizado desde Git devuelve `400`: elimínalo del repositorio, o elimina el marketplace en claude.ai. Requiere el ámbito `write:plugins`.

La eliminación no se puede deshacer, y no existe la eliminación por versión. Para retirar un plugin propiedad de la organización de forma reversible, establece su configuración de instalación para toda la organización en `not_available` (un plugin que heredaba el valor predeterminado de su marketplace obtiene una configuración propia, y [eliminar esa configuración para toda la organización](https://platform.claude.com/docs/es/manage-claude/plugins-api#remove-an-installation-setting) más adelante devuelve el plugin al valor predeterminado), y elimina (o establece en `not_available`) cada configuración de grupo que liste `GET /v1/organizations/plugins/{plugin_id}/installation_settings`, porque la configuración de un grupo anula el valor para toda la organización para sus miembros. Envía estas escrituras una tras otra, no en paralelo (consulta [Establecer una configuración de instalación](https://platform.claude.com/docs/es/manage-claude/plugins-api#set-an-installation-setting)). Un plugin propiedad de un miembro solo se puede retirar mediante esta API eliminándolo, y solo si su marketplace es `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" }
```

## Versiones de plugins

Una versión de plugin es una instantánea inmutable de los archivos de un plugin procedentes de una carga (la respuesta de [Crear una versión](https://platform.claude.com/docs/es/manage-claude/plugins-api#create-a-version) muestra un objeto completo). Sus campos reflejan, para esta versión, los campos de versión servida del plugin (`display_name`, `description`, `manifest_version`, `content_scan`, `components`, `reach`). Además, incluye `release_notes` (tal como se proporcionó con la carga; se muestra en el historial de versiones de claude.ai) y `created_by` (quién la cargó).

Un `{version}` sin el prefijo `pluginver_` devuelve `400` (excepto el literal `latest` donde se indique). Uno que tiene el prefijo pero no identifica una versión de ese plugin devuelve `404`.

### Listar las versiones de un plugin

`GET /v1/organizations/plugins/{plugin_id}/versions` lista las versiones de un plugin, ordenadas por `created_at` de forma descendente; el primer elemento es la versión que identifica `latest_version_id`. `limit` va de 1 a 1,000. Requiere el ámbito `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
  )

  # Obtiene automáticamente más páginas según sea necesario.
  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,
  );

  // Solo esta página; para la siguiente, vuelve a llamar a list() con page: $versions->nextPage.
  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>

### Crear una versión

`POST /v1/organizations/plugins/{plugin_id}/versions` agrega una versión a un plugin propiedad de la organización en un marketplace `manual`. El cuerpo es `multipart/form-data`, con los mismos campos `files[]` y `release_notes`, [requisitos de carga](https://platform.claude.com/docs/es/manage-claude/plugins-api#upload-requirements) y errores de archivo, manifiesto, archivo comprimido y tamaño que [Crear un plugin](https://platform.claude.com/docs/es/manage-claude/plugins-api#create-a-plugin). El nombre cargado (el `name` del manifiesto) debe ser igual al `name` del plugin. Si el plugin no está fijado, la nueva versión normalmente se sirve en cuanto se almacena; si está fijado, la versión se almacena pero no se sirve hasta que cambies la versión servida a ella. Para comprobarlo, compara el `id` de la respuesta con el `served_version_id` del plugin. Devuelve la versión. Requiere el ámbito `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();

      // Construye la parte `files[]` manualmente para que el archivo se envíe con su nombre,
      // que la carga requiere.
      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"
}
```

Además de un `400` para una carga que incumple los [requisitos de carga](https://platform.claude.com/docs/es/manage-claude/plugins-api#upload-requirements) (`413` para un cuerpo de solicitud de más de 200 MB) y las respuestas compartidas (un `403` para un plugin propiedad de un miembro; consulta [Respuestas de error](https://platform.claude.com/docs/es/manage-claude/plugins-api#error-responses)), la solicitud puede fallar con:

| Estado                     | Causa                                                                                                                       | Qué hacer                                                                                                                                                                                     |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400                        | El plugin está en un marketplace sincronizado desde Git, o el nombre cargado difiere del del plugin.                        | Modifica el repositorio en su lugar, o corrige el `name` del manifiesto.                                                                                                                      |
| 409 (sin `error_code`)     | Otra carga a este plugin, o un cambio de versión servida, todavía está en curso.                                            | Vuelve a intentarlo en breve.                                                                                                                                                                 |
| 409 `skill_name_taken`     | El plugin está en el marketplace de biblioteca y la versión agrega una skill con el nombre de una skill de la organización. | Cambia el nombre de la skill o elimina la skill de la organización en claude.ai.                                                                                                              |
| 503 `registration_pending` | La versión se almacenó, pero su registro no se completó.                                                                    | Reenvía la misma solicitud cuando la respuesta incluya `x-should-retry: true` (consulta [Reintentar cargas](https://platform.claude.com/docs/es/manage-claude/plugins-api#retrying-uploads)). |

### Obtener una versión

`GET /v1/organizations/plugins/{plugin_id}/versions/{version}` devuelve una versión. `{version}` es un ID de versión, o `latest` para la versión que identifica `latest_version_id` en el momento de la solicitud. Requiere el ámbito `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>

### Descargar los archivos de una versión

`GET /v1/organizations/plugins/{plugin_id}/versions/{version}/content` descarga los archivos de una versión como el archivo comprimido `.zip` almacenado (`Content-Type: application/zip`). El archivo comprimido se devuelve sea cual sea el resultado de su análisis de contenido, así que puedes inspeccionar versiones que se retienen a los miembros. Se sirve exactamente como se almacenó. Por eso, si el plugin es propiedad de la organización y está en un marketplace `manual`, puedes volver a cargarlo sin cambios como una nueva versión, siempre que cumpla los requisitos de carga actuales.

`{version}` debe ser un ID de versión, no `latest`. Primero lee el `served_version_id` o el `latest_version_id` del plugin, o resuelve `latest` con `GET /v1/organizations/plugins/{plugin_id}/versions/latest`. El nombre de archivo de `Content-Disposition` se deriva del nombre del plugin y no es único, así que nombra los archivos guardados según el ID del plugin y de la versión. Requiere el ámbito `read:plugins`.

Descargar el archivo comprimido de un plugin **propiedad de un miembro** registra un evento `claude_plugin_archive_accessed` en el Activity Feed de la Compliance API. El evento identifica por ID la clave (como `api_actor`), el plugin y su marketplace, la versión y el miembro propietario; no incluye nombres. Descargar el archivo comprimido de un plugin propiedad de la organización no registra nada.

<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() devolvería todo el archivo comprimido como una sola cadena, así que toma la
  // respuesta sin procesar y copia su cuerpo al disco por fragmentos.
  $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)

  # El SDK devuelve el archivo ya leído en memoria, como un StringIO.
  File.binwrite("#{plugin_id}_#{version_id}.zip", archive.string)
  ```
</CodeGroup>

## Configuración de instalación de plugins

Estos endpoints se aplican a plugins propiedad de la organización. Devuelven `404` para un plugin propiedad de un miembro, que en su lugar tiene [elementos compartidos](https://platform.claude.com/docs/es/manage-claude/plugins-api#plugin-shares).

`{target}` puede tomar dos valores:

* El literal `organization`, para la configuración del plugin en toda la organización.
* El ID `rbac_group_` de un grupo, para la configuración de ese grupo.

Cualquier otro valor devuelve `400`. Los ID de grupo se obtienen de `GET /v1/organizations/rbac_groups` (ámbito `read:rbac_groups`; consulta [Administración de usuarios](https://platform.claude.com/docs/es/manage-claude/user-management#groups)).

Una configuración no tiene un `id` propio: se identifica mediante `(plugin_id, target)`. Tampoco registra ningún actor; el actor figura en su evento de actividad `plugin_installation_preference_updated`.

### Listar las configuraciones de instalación de un plugin

`GET /v1/organizations/plugins/{plugin_id}/installation_settings` lista las configuraciones que tiene un plugin propiedad de la organización, ordenadas por `created_at` de forma descendente. Incluye su propia configuración para toda la organización (ausente mientras herede el valor predeterminado de su marketplace) y la configuración de cada grupo. Filtra por `target_type` (`organization` o `rbac_group`). Requiere el ámbito `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"
  )

  # Obtiene automáticamente más páginas según sea necesario.
  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',
  );

  // Solo esta página; para la siguiente, vuelve a llamar a list() con page: $settings->nextPage.
  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>

### Establecer una configuración de instalación

`POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}` establece la configuración de instalación de un destino para un plugin propiedad de la organización, creándola o cambiando el valor que ya tiene. El único campo del cuerpo es `installation_preference` (`required`, `auto_install`, `available` o `not_available`), y es obligatorio. Establecer el valor que el destino ya tiene no cambia nada. Establecer el destino `organization` hace que el plugin deje de heredar el valor predeterminado de su marketplace (`organization_installation_preference_inherited` pasa a ser `false`), incluso cuando el valor es el mismo que el predeterminado, por lo que el plugin ya no sigue los cambios posteriores al valor predeterminado del marketplace. Para devolver el plugin al valor predeterminado de su marketplace, [elimina la configuración para toda la organización](https://platform.claude.com/docs/es/manage-claude/plugins-api#remove-an-installation-setting); las configuraciones de grupo no se ven afectadas. Un destino de grupo debe ser un grupo que tu organización pueda ver en `GET /v1/organizations/rbac_groups`, o la solicitud devuelve `404`. El cambio no altera el `updated_at` del plugin; se registra en el Activity Feed. Devuelve la configuración. Requiere el ámbito `write:plugins`.

Envía las escrituras de configuración de instalación de un plugin de una en una. Si llegan varias escrituras para el mismo plugin al mismo tiempo, el servidor las procesa una tras otra y puede responder a algunas de ellas con `503` en lugar de aplicarlas. Ese `503` incluye `x-should-retry: true`, y es seguro repetir la escritura: espera uno o dos segundos y luego vuelve a enviarla.

<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"
}
```

### Eliminar una configuración de instalación

`DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}` elimina la configuración de instalación de un destino para un plugin propiedad de la organización. Con `{target}` igual a `organization`, elimina la propia configuración para toda la organización del plugin. El plugin vuelve entonces a heredar el valor predeterminado de su marketplace (`organization_installation_preference_inherited` pasa a ser `true`) y sigue los cambios posteriores a ese valor predeterminado; las configuraciones de grupo no se ven afectadas. Con el ID `rbac_group_` de un grupo, elimina la configuración de ese grupo: los miembros del grupo recurren al valor para toda la organización, o a la configuración de otro de sus grupos. Un destino que no tiene una configuración propia devuelve `404`; eso incluye el destino `organization` de un plugin que ya hereda el valor predeterminado de su marketplace. El cambio no altera el `updated_at` del plugin; se registra en el Activity Feed. La respuesta incluye la clave compuesta en lugar de un `id`; para el destino `organization`, su `target` es `{"type": "organization"}`. Requiere el ámbito `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" }
}
```

## Elementos compartidos de plugins

Los elementos compartidos solo existen en plugins propiedad de miembros y son de solo lectura en esta API (consulta [Elementos compartidos](https://platform.claude.com/docs/es/manage-claude/plugins-api#shares)).

### Listar los elementos compartidos de un plugin

`GET /v1/organizations/plugins/{plugin_id}/shares` lista con quién ha compartido su propietario un plugin propiedad de un miembro, ordenado por `granted_at` de forma descendente. Cada elemento compartido apunta a todos los miembros (`organization`), a un grupo (`rbac_group`) o a un miembro concreto (`organization_member`). Filtra por `target_type`.

Un plugin que su propietario no ha compartido devuelve una lista vacía; un plugin propiedad de la organización devuelve `404`. Los elementos compartidos son de solo lectura en esta API. Un elemento compartido de la lista solo da acceso mientras ese tipo de uso compartido esté activado para tu organización en claude.ai (consulta [Elementos compartidos](https://platform.claude.com/docs/es/manage-claude/plugins-api#shares)).

`granted_at` indica cuándo se otorgó el elemento compartido; si el propietario lo modifica después en claude.ai, indica el momento de ese cambio. Requiere el ámbito `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")

  # Obtiene automáticamente más páginas según sea necesario.
  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',
  );

  // Solo esta página; para la siguiente, vuelve a llamar a list() con page: $shares->nextPage.
  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
}
```

## Marketplaces de plugins

Esta API lee [marketplaces](https://platform.claude.com/docs/es/manage-claude/plugins-api#marketplaces) y establece la configuración de instalación predeterminada de un marketplace de la organización. Los marketplaces en sí se crean, se conectan a un repositorio y se eliminan en 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"
}
```

| Campo                             | Descripción                                                                                                                                                                                                                                                    |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                            | El nombre del marketplace. No cambia durante toda su vida útil.                                                                                                                                                                                                |
| `owner`                           | Misma estructura que en el plugin.                                                                                                                                                                                                                             |
| `source`                          | `manual`, `github`, `gitlab` o `public_git`. Consulta [Marketplaces](https://platform.claude.com/docs/es/manage-claude/plugins-api#marketplaces).                                                                                                              |
| `sync_status`                     | Resultado de la sincronización más reciente: `success`, `in_progress`, `failed_content`, `failed_transient`, `failed_auth` o `failed_limits`. Es `null` hasta el primer intento de sincronización, que nunca ocurre en un marketplace cuyo origen es `manual`. |
| `last_sync_ended_at`              | Cuándo terminó el intento de sincronización más reciente, sea cual sea su resultado. En un repositorio conectado que aún no se ha sincronizado, indica cuándo se creó el marketplace. Es `null` en un marketplace que no se sincroniza.                        |
| `last_sync_read_sha`              | El commit que la última sincronización leyó del repositorio. No es necesariamente el commit del que provienen las versiones servidas. Es `null` en un marketplace que no se sincroniza.                                                                        |
| `default_installation_preference` | En marketplaces de la organización: el valor para toda la organización de cada plugin del marketplace que no tiene configuración propia (`not_available` si nunca se estableció). En marketplaces personales: `null`.                                          |

Un `marketplace_id` sin el prefijo `marketplace_` devuelve `400`. Uno que tiene el prefijo pero no se resuelve, o que pertenece a otra organización, devuelve `404`.

### Listar marketplaces

`GET /v1/organizations/plugin_marketplaces` lista los marketplaces de tu organización y los marketplaces personales de los miembros, ordenados por `created_at` de forma descendente. Úsalo para encontrar el ID de un marketplace antes de que contenga algún plugin, ya sea para filtrar la lista de plugins por él o para cargar en él. El marketplace de biblioteca aparece cuando se crea algo en él por primera vez, en claude.ai o mediante esta API. Filtra por `owner_type` (`organization` o `user`) y `source`. `limit` va de 1 a 1,000. Requiere el ámbito `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"
  )

  # Obtiene automáticamente más páginas según sea necesario.
  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,
  );

  // Solo esta página; para la siguiente, vuelve a llamar a list() con page: $marketplaces->nextPage.
  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>

### Obtener un marketplace

`GET /v1/organizations/plugin_marketplaces/{marketplace_id}` devuelve un marketplace. Requiere el ámbito `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>

### Establecer la configuración de instalación predeterminada de un marketplace

`POST /v1/organizations/plugin_marketplaces/{marketplace_id}` establece la configuración de instalación predeterminada de un marketplace propiedad de la organización. Cada plugin del marketplace que no tiene su propia configuración para toda la organización informa este valor predeterminado como su `organization_installation_preference`, incluidos los plugins que se agreguen más adelante. Funciona con marketplaces `manual` y sincronizados; el marketplace personal de un miembro devuelve `403`.

El único campo actualizable es `default_installation_preference`, y es obligatorio. No se puede volver a establecer en `null`: una vez que un marketplace tiene un valor predeterminado, lo conserva, igual que en claude.ai. Un cambio se registra como un único evento `marketplace_updated`, sin eventos por plugin, y no modifica el `updated_at` de ningún plugin.

Si estableces el valor que ya está establecido, no cambia nada, con una excepción: un marketplace cuyo valor predeterminado nunca se estableció informa `not_available`, pero no tiene ninguna configuración guardada. Por eso, su primera escritura (incluso `not_available`) cuenta como un cambio. Devuelve el marketplace. Requiere el ámbito `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>

### Validar el contenido de un marketplace

Dos endpoints informan qué haría una sincronización del contenido de marketplace indicado, sin conectar ni almacenar nada:

* `POST /v1/organizations/plugin_marketplaces/validate_repository` lee un repositorio público de GitHub.
* `POST /v1/organizations/plugin_marketplaces/validate_archive` lee un `.zip` del directorio del marketplace que tú cargas.

Ambos devuelven el mismo informe: si `marketplace.json` está bien formado, qué plugins se omitirían y por qué, y qué plugins se sincronizarían con parte de su contenido excluido. Las comprobaciones son las mismas que ejecuta una sincronización real.

Los problemas con el contenido se devuelven en el informe, no como errores HTTP: la solicitud se completa correctamente con `valid: false`, incluso cuando el repositorio o el archivo comprimido no se pueden leer en absoluto.

Una validación cuenta como una lectura. Además, entre los dos endpoints hay un límite adicional de 10 validaciones por minuto por organización (consulta [Limitación de velocidad](https://platform.claude.com/docs/es/manage-claude/plugins-api#rate-limiting)). No registran nada en el Activity Feed. Una validación puede tardar hasta 120 segundos en devolver una respuesta, así que configura el tiempo de espera de tu cliente por encima de ese valor. Ambos endpoints requieren el ámbito `read:plugins` o `write:plugins` (`read:org_audit` y `read:compliance_org_data` no los otorgan).

El repositorio, y cualquier origen de plugin fuera de él en GitHub, se leen de forma anónima. Por eso, un repositorio privado o un origen de plugin privado se informa como no encontrado. Los orígenes de plugins en hosts distintos de GitHub no se descargan; un plugin así normalmente recibe una advertencia `marketplace_validate_source_not_checked` y se comprueba cuando el marketplace se sincroniza realmente.

Se aplican reglas más estrictas si el repositorio es un marketplace que Anthropic sincroniza en todas las organizaciones, o si el archivo comprimido nombra uno:

* Cada origen de plugin fuera del marketplace debe estar fijado a un SHA de commit completo.
* Los orígenes no fijados o de hosts no compatibles se informan como errores de plugin.
* La rama que se lee es, de forma predeterminada, aquella desde la que se sincroniza ese marketplace.

`validate_repository` recibe un cuerpo JSON con dos campos:

* `repository_url` (obligatorio): la URL `https://` de un repositorio público en github.com.
* `ref` (opcional): un nombre de rama o un SHA de commit completo de 40 caracteres. Si se omite o es `null`, se usa la rama que leería una sincronización, normalmente la rama predeterminada del repositorio.

`validate_archive` recibe `multipart/form-data` con exactamente una parte, `archive`, enviada como parte de archivo con un nombre de archivo. Debe ser un `.zip` del directorio del marketplace que cumpla estas condiciones:

* Tamaño máximo de 32 MB.
* Contenido en la raíz o dentro de una sola carpeta (como lo genera la descarga de un host de Git).
* Solo compresión DEFLATE o STORE.

No se acepta ningún otro campo de formulario.

Valida un repositorio público en una rama:

<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"
        }
      ]
    }
  ]
}
```

| Campo                                   | Descripción                                                                                                                                                                                                                                                      |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `valid`                                 | `true` cuando `marketplace.json` está bien formado y no se omitiría ningún plugin. Las advertencias no lo convierten en `false`.                                                                                                                                 |
| `ref`                                   | El nombre de la rama que se leyó. Es `null` cuando no se indicó ninguna rama y se leyó la predeterminada, cuando se indicó un SHA de commit o cuando se validó un archivo comprimido.                                                                            |
| `commit_sha`                            | El commit que se validó. En un archivo comprimido descargado de un host de Git, es el commit que el host registró en el campo de comentario del archivo ZIP, si lo hay (no se verifica).                                                                         |
| `total_plugin_count`                    | Cuántos plugins declara `marketplace.json`; `0` cuando no se pudo leer.                                                                                                                                                                                          |
| `manifest_error`, `manifest_error_code` | Se establecen cuando no se pudo validar nada: no se pudo leer el origen, o `marketplace.json` falta, está mal formado o supera un límite. Una validación que no terminó en 120 segundos informa `manifest_error_code: "marketplace_validate_deadline_exceeded"`. |
| `plugin_errors`                         | Un `{name, error, error_code}` por cada plugin que una sincronización omitiría.                                                                                                                                                                                  |
| `plugin_warnings`                       | Un `{name, warnings: [{message, error_code}]}` por cada plugin que se sincronizaría con parte de su contenido excluido.                                                                                                                                          |

También puedes validar una copia local del directorio del marketplace como un `.zip`; la respuesta es el mismo informe:

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

      // Pasa un Path para que la parte `archive` se envíe con un nombre de archivo, que este endpoint requiere.
      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>

Los problemas con el contenido nunca hacen fallar la solicitud. La solicitud puede devolver las respuestas que comparten todos los endpoints, como un `403` para una clave que solo tiene `read:org_audit` o `read:compliance_org_data` (consulta [Respuestas de error](https://platform.claude.com/docs/es/manage-claude/plugins-api#error-responses) y [Limitación de velocidad](https://platform.claude.com/docs/es/manage-claude/plugins-api#rate-limiting)). Además, la solicitud en sí puede fallar con:

| Estado | Causa                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Qué hacer                                                                 |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| 400    | En `validate_repository`: el cuerpo no es un objeto JSON; `repository_url` falta, tiene más de 2,048 caracteres, incluye credenciales o no tiene la forma `https://github.com/{owner}/{repo}` (se acepta un sufijo `.git`; no se aceptan otro host, una ruta más larga como el `/tree/main` de la página de una rama, ni un puerto distinto de 443 u 80); `ref` está vacío, tiene más de 255 caracteres, contiene `..` o contiene un carácter distinto de letras ASCII, dígitos, `.`, `_`, `-`, `+` y `/`; o hay otro campo presente. Un `ref` que supera estas comprobaciones pero nombra una rama que el repositorio no tiene no se rechaza: la solicitud se completa correctamente con `valid: false` y `manifest_error` indica que no se encontró la rama. En `validate_archive`: el cuerpo no es `multipart/form-data`; la parte `archive` falta, está repetida o no se envió como parte de archivo con un nombre de archivo; o hay otro campo de formulario presente. | Corrige la solicitud y vuelve a enviarla.                                 |
| 413    | En `validate_archive`: la parte `archive`, o la longitud de cuerpo declarada en la solicitud, supera los 32 MB.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Valida el repositorio por URL en su lugar o reduce el archivo comprimido. |

#### Códigos del informe

Cada hallazgo de un informe tiene un código estable:

* `manifest_error_code`, cuando no se pudo validar nada.
* `error_code` en cada entrada de `plugin_errors`.
* `error_code` en cada advertencia.

Cuando un plugin tiene varios problemas, `error_code` corresponde al primero y `error` une sus mensajes.

Es posible que se agreguen códigos nuevos. Un código no reconocido conserva el significado de su ubicación:

* En `manifest_error_code`, sigue significando que no se pudo validar el contenido.
* En una entrada de `plugin_errors`, sigue significando que el plugin se omitiría.
* En una advertencia, sigue significando que el plugin se sincronizaría.

Los siguientes códigos indican condiciones transitorias, así que la misma solicitud puede completarse correctamente más adelante: `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` y, por lo general, `marketplace_validate_deadline_exceeded`.

## Valores no reconocidos

Cualquier valor de cadena de esta página (tipos de componentes, `reach`, campos de análisis, `source` del marketplace, códigos de error) puede incorporar valores nuevos en cualquier momento. Trata un valor que no reconozcas como tratarías cualquier cadena desconocida, en lugar de generar un error.

## Limitación de velocidad

Las solicitudes de lectura (todos los endpoints `GET` de esta página) comparten un "rate limit" (límite de velocidad) de **300 solicitudes por minuto** por organización. Las solicitudes de escritura comparten un límite de **60 solicitudes por minuto** por organización. Son escrituras crear un plugin o una versión, cambiar la versión servida, eliminar, establecer o eliminar una configuración de instalación y actualizar un marketplace.

Una validación de marketplace (en cualquiera de los dos endpoints) cuenta como una lectura. Además, las validaciones tienen un límite adicional de 10 por minuto por organización entre ambos endpoints. Los dos límites se comprueban antes de leer el cuerpo de la solicitud.

Estos límites se cuentan entre todas las claves de tu organización y son independientes de los demás límites de la Admin API de tu organización. Las solicitudes que superan un límite devuelven **429 Too Many Requests** con un encabezado `retry-after`. Las respuestas incluyen encabezados `anthropic-ratelimit-requests-*` para el límite que se aplica: en la validación de marketplaces, su límite de 10 por minuto; en un `429`, el límite que rechazó la solicitud.

Una carga, un cambio de versión servida o una validación también pueden devolver `429` con `retry-after` cuando el servicio no tiene capacidad momentánea para otra operación. Una carga también devuelve `429` cuando tu organización ha superado su tasa de análisis de contenido. Gestiona todos estos casos de la misma manera: espera lo que indique `retry-after` y vuelve a intentarlo.

Aparte de estos límites, envía de una en una las escrituras de configuración de instalación para el mismo plugin. Cuando llegan varias al mismo tiempo, algunas pueden recibir `503` con `x-should-retry: true`, y se pueden volver a enviar de forma segura después de uno o dos segundos (consulta [Establecer una configuración de instalación](https://platform.claude.com/docs/es/manage-claude/plugins-api#set-an-installation-setting)).

## Paginación

Los endpoints de listado usan un **"opaque cursor" (cursor opaco)**. La primera solicitud devuelve hasta `limit` filas más un cursor `next_page`; pasa el cursor sin cambios como parámetro `page` en la siguiente solicitud y repite hasta que `next_page` sea `null`. Trata la cadena del cursor como opaca: no la analices, modifiques ni construyas tú mismo. [Listar plugins](https://platform.claude.com/docs/es/manage-claude/plugins-api#list-plugins) puede devolver una página con menos de `limit` plugins, o ninguno, mientras `next_page` sigue establecido, así que sigue solicitando páginas hasta que `next_page` sea `null`. Los iteradores de listado de los SDK de Python, TypeScript, C#, Go, Java y Ruby y la CLI (excepto con `--format raw`) lo hacen por ti. Solicitan la siguiente página mientras `next_page` esté establecido, por lo que una página corta o vacía no los detiene. En PHP y curl, solicita cada página tú mismo y pasa su `next_page` como `page`.

`limit` tiene un valor predeterminado de 20 y un mínimo de 1. El máximo es 100 para plugins, configuraciones de instalación y elementos compartidos, y 1,000 para versiones y marketplaces. Cada lista se ordena de más reciente a más antiguo.

## Respuestas de error

Las respuestas de error siguen la estructura estándar documentada en [Errores](https://platform.claude.com/docs/es/api/errors). Indica el `request_id` del cuerpo de la respuesta cuando te comuniques con soporte.

| Estado | Significado                                                                                                                                                                                                                                                                                                                         |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | Entrada no válida, o la operación no se aplica a este plugin o marketplace (consulta la sección de cada endpoint). También se devuelve cuando el endpoint no reconoce un parámetro de consulta, y cuando la organización no es una organización de Claude Enterprise (`this endpoint is not supported for this organization type`). |
| 401    | Falta el encabezado `x-api-key`, o no se reconoce la clave.                                                                                                                                                                                                                                                                         |
| 403    | A la clave le falta el alcance requerido, o la solicitud carga archivos a un plugin o marketplace personal de un miembro, cambia su versión servida o establece su valor predeterminado. (Sí se permite eliminar el plugin de un miembro).                                                                                          |
| 404    | No se encontró el recurso. También se devuelve cuando la solicitud omite el valor `anthropic-beta`, o cuando la API no está habilitada para tu organización, de modo que los endpoints aparecen como inexistentes.                                                                                                                  |
| 409    | Un nombre ya está en uso, un análisis de contenido aún está en curso o hay una carga en conflicto en progreso.                                                                                                                                                                                                                      |
| 413    | El cuerpo de la solicitud supera el límite de tamaño: 200 MB para una carga, 32 MB para la validación de un marketplace.                                                                                                                                                                                                            |
| 429    | Se excedió el "rate limit" (límite de velocidad). Consulta [Limitación de velocidad](https://platform.claude.com/docs/es/manage-claude/plugins-api#rate-limiting).                                                                                                                                                                  |
| 500    | Error interno.                                                                                                                                                                                                                                                                                                                      |
| 503    | Temporal. También se devuelve cuando llegan al mismo tiempo varias escrituras de configuración de instalación para un mismo plugin; envíalas de una en una. Reintenta con "backoff" (espera progresiva entre reintentos), excepto en el caso de `registration_pending` (consulta la tabla siguiente).                               |

Cuando un mismo estado tiene varias causas que manejarías de forma distinta, el error también incluye `error.details.error_code`, y `error.details.plugin_id` o `error.details.plugin_version_id` cuando la causa involucra alguno de ellos:

```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`                                    | Estado | Significado y qué hacer                                                                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plugin_name_taken`                             | 409    | Ya existe un plugin con este nombre en el marketplace. `details.plugin_id` es ese plugin. Si estás reintentando una creación cuya respuesta perdiste, continúa con ese plugin. Cuando `plugin_id` no está presente, el nombre lo tiene una skill independiente: carga con otro nombre o elimina la skill en claude.ai. |
| `skill_name_taken`                              | 409    | El plugin está en el marketplace de la biblioteca y una de sus skills tiene el mismo nombre que una skill de la organización (una skill que un administrador cargó para toda la organización en claude.ai). `details.skill_name` indica su nombre. Cambia el nombre de una de ellas o elimínala.                       |
| `registration_pending`                          | 503    | Los archivos se almacenaron, pero las skills del plugin aún no se pudieron poner a disposición de los miembros. Consulta [Reintentar cargas](https://platform.claude.com/docs/es/manage-claude/plugins-api#retrying-uploads).                                                                                          |
| `scan_pending`                                  | 409    | El análisis de contenido de la versión aún está en curso. Reintenta cuando termine.                                                                                                                                                                                                                                    |
| `scan_failed`                                   | 400    | El análisis de contenido de la versión falló, produjo un error o no llegó a un veredicto, por lo que no se puede servir. Elige otra versión.                                                                                                                                                                           |
| `cmek_key_disabled`, `cmek_key_network_blocked` | 400    | La clave de cifrado administrada por el cliente de tu organización no está disponible. Consulta [Claves de cifrado administradas por el cliente](https://platform.claude.com/docs/es/manage-claude/plugins-api#customer-managed-encryption-keys).                                                                      |

Es posible que se agreguen nuevos códigos. Trata un código que no reconozcas de la misma forma en que tratas su estado.

### Reintentar cargas

Ningún endpoint acepta un `Idempotency-Key`. Cambiar la versión servida, establecer una configuración de instalación y establecer un valor predeterminado de marketplace son operaciones seguras de repetir. Una eliminación repetida, o una eliminación repetida de una configuración de instalación, devuelve `404`.

Una carga que devuelve un error no almacenó nada, con una excepción: `503` con `error_code: "registration_pending"`. Después de almacenar los archivos de una carga, el servidor registra las skills de la nueva versión en claude.ai, que es lo que las hace utilizables por los miembros; `registration_pending` significa que los archivos se almacenaron pero ese último paso no se completó. Cargar los mismos archivos una vez más lo completa (y almacena una versión idéntica adicional):

* En `POST /v1/organizations/plugins`, el plugin *sí* se creó, y la respuesta incluye `x-should-retry: false`: no vuelvas a enviar la creación (un reenvío devuelve `409 plugin_name_taken`); en su lugar, carga los mismos archivos como una versión de `details.plugin_id`.
* En `POST /v1/organizations/plugins/{plugin_id}/versions`, la versión *sí* se almacenó (`details.plugin_version_id`); vuelve a enviar la misma solicitud cuando la respuesta incluya `x-should-retry: true`, y no lo hagas cuando incluya `false`.

Si se pierde la respuesta de una creación, vuelve a intentarla: el reintento devuelve `409 plugin_name_taken` con el ID del plugin en `details.plugin_id`, y continúas con ese plugin. Reintentar una creación de versión cuya respuesta se perdió almacena una segunda versión idéntica. Para evitarlo, registra el `latest_version_id` del plugin antes de cada carga; si se pierde una respuesta, lee el plugin y vuelve a intentarlo solo si `latest_version_id` no ha cambiado.

## Eventos del Activity Feed

Cada escritura realizada a través de esta API se registra en el [Activity Feed de la Compliance API](https://platform.claude.com/docs/es/manage-claude/compliance-activity-feed) de tu organización, atribuida a la clave de API como un `api_actor` que incluye su ID `apikey_`. El mismo actor aparece en `created_by` en los plugins y las versiones que crea la clave.

| Evento                                   | Se emite cuando                                                                                                                                                                                         |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `claude_plugin_created`                  | Se crea un plugin mediante una carga (aquí o en claude.ai) o mediante una solicitud de publicación aceptada. Un plugin creado por una sincronización de Git emite solo `claude_plugin_version_created`. |
| `claude_plugin_version_created`          | Se almacena una versión. Las versiones almacenadas por una sincronización de Git se atribuyen a un `system_actor`.                                                                                      |
| `claude_plugin_updated`                  | Se carga una nueva versión a un plugin existente.                                                                                                                                                       |
| `claude_plugin_served_version_updated`   | Cambia la versión servida.                                                                                                                                                                              |
| `claude_plugin_deleted`                  | Se elimina un plugin de forma individual, aquí o en claude.ai.                                                                                                                                          |
| `plugin_installation_preference_updated` | Se establece o se elimina una configuración de instalación.                                                                                                                                             |
| `marketplace_created`                    | La primera carga crea el marketplace de la biblioteca.                                                                                                                                                  |
| `marketplace_updated`                    | Cambia la configuración de instalación predeterminada de un marketplace, o un administrador o propietario inicia una sincronización en claude.ai.                                                       |
| `marketplace_deleted`                    | Se elimina un marketplace en claude.ai junto con sus plugins (sin eventos por plugin).                                                                                                                  |
| `claude_plugin_archive_accessed`         | Se descarga el archivo de un plugin propiedad de un miembro.                                                                                                                                            |
| `claude_plugin_security_scan_completed`  | Finaliza un análisis de contenido.                                                                                                                                                                      |

Los IDs de plugin, versión y marketplace en estos eventos son los mismos IDs que devuelve esta API. `plugin_installation_preference_updated` identifica el plugin por su `name` y su `marketplace_id` en lugar de por su `id`.

Cambiar el valor predeterminado de un marketplace registra un evento `marketplace_updated` y ningún evento por plugin, aunque cambia el valor de cada plugin que hereda el valor predeterminado. Las lecturas no se registran, excepto las descargas del archivo de un plugin propiedad de un miembro. Una escritura que no cambia nada no registra nada.

Los permisos compartidos otorgados o retirados en claude.ai aparecen en el feed como eventos `role_assignment_granted` y `role_assignment_revoked`. Esta API no informa sobre eliminaciones: un plugin eliminado simplemente no aparece en la siguiente lista. Un plugin eliminado por una sincronización de Git, por la eliminación de su marketplace (un evento `marketplace_deleted`) o por la eliminación de la cuenta de un miembro o de la organización no emite ningún evento por plugin, así que vuelve a listar el inventario completo periódicamente para detectar las eliminaciones.

## Claves de cifrado administradas por el cliente

Si tu organización usa una [clave de cifrado administrada por el cliente](https://platform.claude.com/docs/es/manage-claude/cmek), la `description`, las `release_notes`, los `components` y los archivos de una versión se cifran con ella. Mientras la clave no esté disponible:

* Las lecturas y los listados siguen funcionando, y `description`, `release_notes` y `components` se devuelven como `null`.
* Las descargas de archivos, las creaciones, las creaciones de versiones y los cambios de versión servida devuelven `400` con `cmek_key_disabled` o `cmek_key_network_blocked`.
* Eliminar un plugin del marketplace de la biblioteca devuelve `400 cmek_key_disabled` y no elimina nada, porque primero se deben retirar sus skills de claude.ai y eso requiere la clave. Las demás eliminaciones, las configuraciones de instalación y los valores predeterminados de marketplace funcionan con normalidad.

Restaurar la clave resuelve todos estos casos.

## Consulta también

<CardGroup cols={2}>
  <Card title="Crear una clave de API de administrador" href="https://platform.claude.com/docs/es/manage-claude/admin-api-keys">
    Donde tu propietario principal crea una clave con alcance definido.
  </Card>

  <Card title="Administración de usuarios" href="https://platform.claude.com/docs/es/manage-claude/user-management">
    Los endpoints de grupos que proporcionan los IDs `rbac_group_` que se usan en las configuraciones de instalación.
  </Card>

  <Card title="Activity Feed de la Compliance API" href="https://platform.claude.com/docs/es/manage-claude/compliance-activity-feed">
    Donde se registran las escrituras de plugins y las descargas de archivos de miembros.
  </Card>

  <Card title="APIs de análisis" href="https://platform.claude.com/docs/es/manage-claude/analytics-api">
    Informes de uso de plugins y skills para Claude Enterprise.
  </Card>
</CardGroup>
