API de plugins
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.
Endpoints
La API expone 18 endpoints en cinco recursos:
| Recurso | Endpoints |
|---|---|
| Plugins: enumera 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/pluginsPOST /v1/organizations/pluginsGET /v1/organizations/plugins/{plugin_id}POST /v1/organizations/plugins/{plugin_id}DELETE /v1/organizations/plugins/{plugin_id} |
| Versiones de plugins: enumera 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}/versionsPOST /v1/organizations/plugins/{plugin_id}/versionsGET /v1/organizations/plugins/{plugin_id}/versions/{version}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 la configuración de un grupo | GET /v1/organizations/plugins/{plugin_id}/installation_settingsPOST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}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 del marketplace antes de conectarlo | GET /v1/organizations/plugin_marketplacesGET /v1/organizations/plugin_marketplaces/{marketplace_id}POST /v1/organizations/plugin_marketplaces/{marketplace_id}POST /v1/organizations/plugin_marketplaces/validate_repositoryPOST /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 en las API de análisis. 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 alcancewrite:pluginso ambos en claude.ai > Configuración de la organización > API. Consulta Crear una clave de API de administrador. - Cada solicitud lleva tres encabezados:
x-api-key,anthropic-version: 2023-06-01yanthropic-beta: ce-plugins-2026-09-01.
Los SDK de Python, TypeScript, C#, Go, Java, PHP y Ruby exponen estos endpoints en client.beta.organization, y la CLI ant 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. En los ejemplos de listado de Python, TypeScript, C#, Go, Java y Ruby y en la CLI, el SDK obtiene más páginas a medida que iteras, por lo que limit establece el tamaño de página, no el total; los ejemplos de PHP y curl devuelven una sola página (consulta Paginación).
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:
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}"){
"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 y de la API de cumplimiento. 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). Cada una de estas descargas registra un evento claude_plugin_archive_accessed en el feed de actividad de la API de cumplimiento, que identifica la clave, el plugin, la versión y el miembro (consulta Eventos del feed de actividad). 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) 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.
manualsignifica que los plugins se suben, en claude.ai o, para un marketplace de la organización, a través de esta API.github,gitlabypublic_gitsignifican 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 esmanual. Subir versiones y elegir la versión servida devuelven403. 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, por lo que puedes revisar y eliminar el contenido de un miembro que se fue. Se eliminan cuando se elimina la cuenta del miembro.
Versiones y la versión servida
Cada subida crea una nueva versión inmutable, ya sea que 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 sigue a la más reciente, y cada nueva versión se sirve en cuanto se almacena.
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 escaneo de contenido activado, esa primera fijación devuelve 409 scan_pending hasta que se complete el escaneo de la versión actual, y 400 scan_failed si el escaneo se completó con fail o unknown, o tuvo un error (se acepta warn). 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. Para avanzar, hazlo 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 de marketplace, organization_installation_preference y default_installation_preference):
| Valor | Lo que ven los miembros |
|---|---|
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). Un miembro obtiene un valor según estas reglas:
- 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 enorganization_installation_preference, conorganization_installation_preference_inherited: truemientras provenga del valor predeterminado del marketplace. - Un miembro que no pertenece a ningún grupo con una configuración para el plugin obtiene el valor para toda la organización.
- 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 impide permanentemente que el plugin herede el valor predeterminado de su marketplace, como explica Establecer una configuración de instalación).
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á.
Escaneo de contenido
El escaneo de contenido es una configuración de la organización en claude.ai. Cuando está activado, las versiones recién almacenadas se escanean (claude.ai exime a algunas) y el resultado se informa en content_scan; una versión que no se escaneó, por ejemplo, una almacenada antes de que se activara el escaneo, tiene content_scan: null. El escaneo no se ofrece a organizaciones que usan claves de cifrado administradas por el cliente o retención de datos cero.
Mientras el escaneo está activado, a los miembros se les sirve un plugin solo cuando el escaneo de su versión servida está completed con pass o warn. Mientras se ejecuta el escaneo, o después de que falla, tiene 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 escaneó (content_scan: null) se sirve normalmente.
En un plugin que no está fijado, cada subida se convierte de inmediato en la versión servida. Los miembros pierden el plugin hasta que el escaneo de la nueva versión se aprueba, y siguen sin él si el escaneo falla. Si los miembros deben conservar la versión actual mientras se escanea una nueva, fija primero el plugin (consulta Versiones y la versión servida).
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 del plugin muestra solo el escaneo de su versión servida. Cambiar la versión servida a una versión cuyo escaneo aún se está ejecutando devuelve 409 scan_pending; a una cuyo escaneo falló, 400 scan_failed.
Reach
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 o un comando que aprueba previamente herramientas para sí mismo (allowed-tools en su frontmatter). 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 ninguna de sus skills o comandos 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 enumera, 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 reach no se pudo determinar porque no se pudo leer uno de sus archivos de skill o de comando; 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
.zipo.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 unname. Se rechaza unSKILL.mdsuelto sin manifiesto. - Un
SKILL.mdde nivel superior cuyo frontmatter declara componentes de plugin se combina con el manifiesto;plugin.jsonprevalece dondequiera que ambos establezcan un valor. namepuede 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.displayNametiene como máximo 64 caracteres ydescriptioncomo máximo 500.- Cada
SKILL.mdnecesita un frontmatter YAML válido connameydescription, 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
.zipanidados. 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 de400. 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.
- Encuentra el marketplace al que vas a subir con
GET /v1/organizations/plugin_marketplaces?owner_type=organization, u omitemarketplace_idpara usar el marketplace de biblioteca. - En el primer lanzamiento, crea el plugin con
POST /v1/organizations/plugins. En cada lanzamiento posterior, registra ellatest_version_iddel plugin y luego sube una versión conPOST /v1/organizations/plugins/{plugin_id}/versions. Si se pierde la respuesta de la subida, lee el plugin y vuelve a intentarlo solo silatest_version_idno cambió (consulta Reintentar subidas). - 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_iden 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. - Cuando el escaneo de contenido esté activado, consulta periódicamente
GET /v1/organizations/plugins/{plugin_id}/versions/{version}hasta quecontent_scan.statusya no seaprocessing, y promueve solo cuando seacompletedconpassowarn. - Promueve la compilación 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 en un grupo piloto y luego para todos
-
Busca el ID del grupo piloto con
GET /v1/organizations/rbac_groups. Esa llamada necesita el alcanceread:rbac_groups, que requiere una clave creada para todas las organizaciones vinculadas (consulta Administración de usuarios). Los siguientes pasos necesitanwrite:plugins, que actúa solo sobre la organización en la que se creó su clave, así 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. -
Dale al grupo su propia configuración, por ejemplo
auto_install, conPOST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}, donde{target}es el IDrbac_group_del grupo, mientras el valor para toda la organización se mantiene ennot_available. Solo los miembros del grupo obtienen el plugin. -
Cuando termine el piloto, establece el valor para toda la organización (esto impide permanentemente que el plugin herede el valor predeterminado de su marketplace, como explica Establecer una configuración de instalación) y luego elimina la configuración del grupo para que el grupo vuelva a seguir a la organización:
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}")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 deavailablemantendría a esos miembros enavailable.
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 escaneo de contenido.
- Recorre las páginas de
GET /v1/organizations/plugins?limit=100hasta quenext_pageseanull, pasando tú mismo elnext_pagede cada página comopageen lugar de usar un iterador de listas del SDK, que puede detenerse antes de tiempo en esta lista (consulta Paginación). Lee elreachy elcontent_scande cada plugin de esa lista en cada ejecución: un veredicto de escaneo que llega más tarde no modificaupdated_at.updated_atte indica qué plugins tienen contenido nuevo o una nueva versión servida desde la última ejecución (vale la pena volver a descargar el archivo comprimido); volver a enumerar todo también es 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. - Marca cada plugin cuyo
reachsearemote(declara un servidor MCP o una CLI), o cuyocontent_scan.assessmentseafailounknown. - 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). - Para retirar un plugin a los miembros mientras lo revisas, consulta Eliminar un plugin para ver las opciones reversible (propiedad de la organización) y permanente.
Plugins
El objeto de plugin describe un plugin en uno de los marketplaces de tu organización o en el marketplace personal de un miembro (la respuesta de Inicio rápido muestra uno completo). Sus campos display_name, description, manifest_version, content_scan, components y reach describen su versión servida, por lo que una sola llamada de listado muestra lo que se sirve 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. |
served_version_pinned | false mientras la versión servida sigue cada nueva versión; true una vez que se ha elegido una versión explícitamente. |
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 hay un creador registrado, 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). Propiedad de un miembro: ambos null. |
content_scan | El resultado del escaneo de la versión servida, un objeto con status, assessment y reason (descritos después de esta tabla). null cuando nunca se escaneó. |
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, enumerados 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 está registrado. |
reach | contained, privileged o remote. Consulta Reach. |
updated_at | Cambia solo cuando se almacena una nueva versión o cambia la versión servida. No cambia por configuraciones de instalación, uso compartido ni nuevos resultados de escaneo. |
El objeto content_scan:
| Campo | Descripción |
|---|---|
status | processing mientras se ejecuta el escaneo, 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 puede informarlo). A los miembros no se les sirve una versión cuyo escaneo esté en processing o errored; volver a subir el contenido como una nueva versión obtiene un nuevo escaneo. |
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 escaneo anterior a que se registraran los motivos. |
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 le muestra al miembro y que este no controla. |
remote-code-instruction-loader | Indica a Claude que descargue y ejecute contenido externo, o que siga instrucciones de él, 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 le indica a Claude que no revele lo que hace. |
undisclosed-promotion-injection | Inserta contenido promocional no divulgado 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 escaneo no pudo verificar lo que hace. |
other | Cualquier otra preocupación, incluida una más reciente que esta lista. |
Un plugin_id que no tiene el prefijo plugin_ devuelve 400. Un plugin_id que tiene 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. Requiere el alcance read:plugins.
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}")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. 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:
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}"){
"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:
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}")Una creación puede fallar con un 400 si la carga incumple los requisitos de carga, 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). 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. |
| 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). |
Obtener un plugin
GET /v1/organizations/plugins/{plugin_id} devuelve un plugin. Requiere el ámbito read:plugins.
client = anthropic.Anthropic()
plugin = client.beta.organization.plugins.retrieve("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")
print(f"id: {plugin.id}")
print(f"name: {plugin.name}")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 "pins" (fija) el plugin. Actualmente, un plugin fijado no se puede desfijar, ni aquí ni en claude.ai (consulta Versiones y la versión servida).
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 poder servirse a los miembros (consulta Análisis de contenido).
Si pasas la versión que ya se sirve en un plugin fijado, no cambia nada. Si la pasas en un plugin no fijado, el plugin queda fijado en esa versión, y las cargas posteriores dejan de servirse automáticamente. Devuelve el plugin. Requiere el ámbito write:plugins.
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}"){
"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"
}La solicitud puede devolver 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). Además, 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 no tiene el 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. |
409 (sin error_code) | Una carga en este plugin u otro cambio de versión servida sigue 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 de forma permanente un plugin y todas sus versiones, igual que cuando un administrador lo elimina en claude.ai. Funciona con cualquier plugin de un marketplace manual, incluido el plugin de un miembro, aunque ese miembro ya haya dejado la organización.
Cuando la eliminación termina, el plugin, sus versiones y sus archivos desaparecen de todas las lecturas, y ya no se sirven a los miembros. Si el plugin es propiedad de la organización, también se eliminan sus configuraciones de instalación. Si es propiedad de un miembro, se retiran sus elementos compartidos y el plugin también desaparece para su propietario.
Un plugin de un marketplace sincronizado desde Git devuelve 400: quítalo del repositorio o elimina el marketplace en claude.ai. Requiere el ámbito write:plugins.
La eliminación no se puede deshacer, y no es posible eliminar versiones individuales. Si prefieres retirar un plugin propiedad de la organización de forma reversible, sigue estos pasos:
- Establece su configuración de instalación para toda la organización en
not_available. Si el plugin heredaba el valor predeterminado de su marketplace, a partir de ese momento conserva una configuración propia. - Elimina (o establece en
not_available) cada configuración de grupo que listeGET /v1/organizations/plugins/{plugin_id}/installation_settings. Esto es necesario porque la configuración de un grupo prevalece sobre el valor de 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). Un plugin propiedad de un miembro solo se puede retirar mediante esta API eliminándolo, y únicamente si su marketplace es manual.
client = anthropic.Anthropic()
deleted_plugin = client.beta.organization.plugins.delete(
"plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
)
print(f"id: {deleted_plugin.id}"){ "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 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.
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}")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. Usa los mismos campos files[] y release_notes que Crear un plugin, con los mismos requisitos de carga y los mismos errores de archivo, manifiesto, archivo comprimido y tamaño. El nombre cargado (el name del manifiesto) debe ser igual al name del plugin.
Si el plugin no está fijado, la nueva versión 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.
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}"){
"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"
}La solicitud puede fallar con un 400 si la carga incumple los requisitos de carga, o con un 413 si el cuerpo de la solicitud supera los 200 MB. También puede devolver las respuestas compartidas, como un 403 para un plugin propiedad de un miembro (consulta Respuestas de error). Además, puede fallar con:
| Estado | Causa | Qué hacer |
|---|---|---|
| 400 | El plugin está en un marketplace sincronizado desde Git, o el nombre cargado difiere del nombre del plugin. | Modifica el repositorio en su lugar o corrige el name del manifiesto. |
409 (sin error_code) | Otra carga en este plugin, o un cambio de versión servida, sigue 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). |
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.
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}")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.
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")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.
{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).
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.
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}")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: la crea o cambia el valor que ya tiene. El único campo del cuerpo es installation_preference (required, auto_install, available o not_available), y es obligatorio. Si estableces 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 si el valor es igual al predeterminado. Esto no se puede deshacer, porque la configuración para toda la organización no se puede eliminar. Por lo tanto, el plugin ya no sigue los cambios posteriores del valor predeterminado del marketplace.
Un destino de grupo debe ser un grupo que tu organización pueda ver en GET /v1/organizations/rbac_groups; de lo contrario, la solicitud devuelve 404. El cambio no modifica 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 con 503 en lugar de aplicarlas. Ese 503 incluye x-should-retry: true, y la escritura se puede repetir de forma segura: espera uno o dos segundos y vuelve a enviarla.
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}"){
"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 la configuración de instalación de un grupo
DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target} elimina la configuración de un grupo para un plugin propiedad de la organización. Los miembros de ese grupo pasan a usar el valor de toda la organización, o la configuración de otro de sus grupos.
La configuración para toda la organización no se puede eliminar una vez establecida, igual que en claude.ai: un {target} de organization devuelve 400. En su lugar, cambia su valor. Un grupo que no tiene ninguna configuración para este plugin devuelve 404. La respuesta incluye la clave compuesta en lugar de un id. Requiere el ámbito write:plugins.
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}"){
"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).
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).
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.
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}"){
"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 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.
{
"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. |
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.
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}")Obtener un marketplace
GET /v1/organizations/plugin_marketplaces/{marketplace_id} devuelve un marketplace. Requiere el ámbito read:plugins.
client = anthropic.Anthropic()
marketplace = client.beta.organization.plugin_marketplaces.retrieve(
"marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
)
print(f"id: {marketplace.id}")
print(f"name: {marketplace.name}")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.
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}")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_repositorylee un repositorio público de GitHub.POST /v1/organizations/plugin_marketplaces/validate_archivelee un.zipdel 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). 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 URLhttps://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 esnull, 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:
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}"){
"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:
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}")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 y Limitación de velocidad). 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_codeen cada entrada deplugin_errors.error_codeen 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).
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 puede devolver una página con menos de limit plugins, o sin ninguno, mientras next_page sigue establecido. Por eso, sigue solicitando páginas hasta que next_page sea null. Los iteradores de listado de los SDK obtienen más páginas a medida que iteras, pero se detienen en la primera página vacía, así que en la lista de plugins pueden terminar antes de tiempo. Cuando necesites todos los plugins, como en el flujo de trabajo de inventario de seguridad, 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. Todas las listas se ordenan de la más reciente a la más antigua.
Respuestas de error
Las respuestas de error siguen la estructura estándar documentada en Errores. 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. |
| 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:
{
"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. |
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. |
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 la configuración de instalación de un grupo, 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 permite que los miembros las usen; 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 incluyex-should-retry: false: no vuelvas a enviar la creación (un reenvío devuelve409 plugin_name_taken); en su lugar, carga los mismos archivos como una versión dedetails.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 incluyax-should-retry: true, y no lo hagas cuando incluyafalse.
Si se pierde la respuesta de una creación, reinténtala: el reintento devuelve 409 plugin_name_taken con el ID del plugin en details.plugin_id, y continúas con ese plugin. Reintentar la creación de una 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 reintenta 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 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, 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_notesycomponentsse devuelven comonull. - Las descargas de archivos, las creaciones, las creaciones de versiones y los cambios de versión servida devuelven
400concmek_key_disabledocmek_key_network_blocked. - Eliminar un plugin del marketplace de la biblioteca devuelve
400 cmek_key_disabledy 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
Donde tu propietario principal crea una clave con alcance definido.
Los endpoints de grupos que proporcionan los IDs rbac_group_ que se usan en las configuraciones de instalación.
Donde se registran las escrituras de plugins y las descargas de archivos de miembros.
Informes de uso de plugins y skills para Claude Enterprise.
Was this page helpful?