{"id":84043,"date":"2026-08-05T12:01:52","date_gmt":"2026-08-05T10:01:52","guid":{"rendered":"https:\/\/kinsta.com\/es\/?p=84043&#038;preview=true&#038;preview_id=84043"},"modified":"2026-08-05T14:00:45","modified_gmt":"2026-08-05T12:00:45","slug":"api-abilities-wordpress","status":"publish","type":"post","link":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/","title":{"rendered":"Primeros pasos con la API Abilities de WordPress: Una gu\u00eda pr\u00e1ctica"},"content":{"rendered":"<p>La API de Abilities, introducida en <a href=\"https:\/\/kinsta.com\/es\/blog\/wordpress-6-9\/#abilities-api\">WordPress 6.9<\/a>, establece un lenguaje com\u00fan que permite a todos los componentes de WordPress \u2014tanto del n\u00facleo como de los plugins\u2014 mostrar su funcionalidad de una forma unificada y comprensible tanto para las personas como para las m\u00e1quinas. Esto hace que tu sitio de WordPress est\u00e9 preparado para integrarse con herramientas de automatizaci\u00f3n externas de forma estandarizada y segura.<\/p>\n<p>Si te est\u00e1s preguntando cu\u00e1les podr\u00edan ser algunos casos de uso de la API Abilities, piensa en un modelo de IA que gu\u00ede al usuario a lo largo del proceso de compra e incluso le permita completar la compra sin tener que visitar tu sitio web de comercio electr\u00f3nico. O piensa en un <a href=\"https:\/\/kinsta.com\/es\/blog\/como-configurar-pipeline-ci-cd\/\">pipeline de CI\/CD en GitHub Actions<\/a> que procese texto extra\u00eddo de un archivo de audio o v\u00eddeo y lo env\u00ede a WordPress para su publicaci\u00f3n. Los casos de uso son infinitos.<\/p>\n<p>La API Abilities cambia por completo el papel de WordPress dentro del ecosistema. Ya no es solo un blog, ni siquiera un CMS; ahora, WordPress funciona como un motor de ejecuci\u00f3n distribuido que se puede coordinar desde fuera, como una especie de sistema operativo, totalmente preparado para agentes aut\u00f3nomos.<\/p>\n<p>\u00bfTienes curiosidad por saber m\u00e1s? Vamos a profundizar en el tema.<br \/>\n<div><\/div><kinsta-auto-toc heading=\"Table of Contents\" list-style=\"arrow\" selector=\"h2\" count-number=\"-1\"><\/kinsta-auto-toc><\/p>\n<h2>Para qu\u00e9 sirve una ability<\/h2>\n<p>Una ability (o capacidad) es una funcionalidad detectable y ejecutable en un sitio de WordPress que permite realizar operaciones espec\u00edficas para entidades externas (como modelos de IA) o componentes internos.<\/p>\n<p>La API se puede usar para cosas como:<\/p>\n<ul>\n<li>Buscar contenido o realizar operaciones espec\u00edficas en la base de datos<\/li>\n<li>Leer los ajustes de configuraci\u00f3n del sitio<\/li>\n<li>Crear una entrada<\/li>\n<li>Convertir una estructura JSON en bloques de Gutenberg<\/li>\n<\/ul>\n<p>Exponer una ability significa hacer que una funcionalidad concreta sea interoperable. Para que una ability pueda detectarse y utilizarse, primero tiene que registrarse en un cat\u00e1logo centralizado. Solo as\u00ed WordPress y los modelos de IA podr\u00e1n detectarla, entender su finalidad e invocarla cuando sea necesario.<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>Hay que aclarar algo: un modelo de IA nunca tiene acceso directo a tu sitio. Solo puede pedirle a WordPress que ejecute una operaci\u00f3n (por ejemplo, \u00abdame el n\u00famero total de entradas del sitio\u00bb) necesaria para completar su tarea.<\/p>\n<\/aside>\n\n<p>Por defecto, las funcionalidades de tus plugins est\u00e1n totalmente aisladas. Al registrar una ability, declaras que la l\u00f3gica subyacente est\u00e1 disponible como servicio para todo el ecosistema.<\/p>\n<p>Veamos un ejemplo. Si tu plugin tiene una funci\u00f3n que convierte un objeto JSON inicial en contenido estructurado listo para los bloques de Gutenberg, puedes registrarla como una ability. Esto permite que otras herramientas con los permisos necesarios activen exactamente la misma funci\u00f3n.<\/p>\n<p>En nuestro tutorial anterior sobre <a href=\"https:\/\/kinsta.com\/es\/blog\/ia-wordpress\/\">Clientes de IA de WordPress<\/a>, el plugin se encargaba de la l\u00f3gica principal de enviar un archivo de audio al modelo de IA, que a su vez devolv\u00eda una respuesta estructurada en JSON para generar bloques de Gutenberg. Sin embargo, esa funcionalidad se limitaba a nuestro plugin. Al registrar este proceso como una ability, se separa la ejecuci\u00f3n, y cualquier entidad externa puede activar toda la l\u00f3gica del plugin simplemente pasando un objeto JSON que contenga el ID de un archivo de audio.<\/p>\n<p><strong>Una ability act\u00faa como un contrato formal<\/strong> entre la l\u00f3gica PHP subyacente y cualquier entidad que solicite su ejecuci\u00f3n. El contrato especifica los datos que la ability espera como entrada, su prop\u00f3sito y el esquema de datos que devuelve como salida.<\/p>\n<p>Cuando registras una ability, se a\u00f1ade al <a href=\"https:\/\/make.wordpress.org\/ai\/2025\/07\/17\/abilities-api\/\" target=\"_blank\" rel=\"noopener noreferrer\">registro de abilities<\/a> de tu sitio. A partir de ese momento, <strong>WordPress act\u00faa como una pasarela segura<\/strong>: verifica la autenticaci\u00f3n y valida los datos entrantes seg\u00fan el esquema establecido por el contrato. WordPress redirige la solicitud a la funci\u00f3n PHP subyacente solo si el payload cumple estrictamente con el contrato.<\/p>\n<p><b>Una ability es agn\u00f3stica.<\/b> WordPress no necesita saber qu\u00e9 entidad concreta solicita el acceso; solo comprueba que la solicitud est\u00e9 autorizada y cumpla con las restricciones del contrato.<\/p>\n<p>Al registrar una ability, tu plugin ya no es solo una extensi\u00f3n con su propia l\u00f3gica interna, sino que se convierte en un proveedor de servicios para todo el ecosistema. Ya se trate de una app m\u00f3vil, un script de automatizaci\u00f3n como Make.com o <a href=\"https:\/\/kinsta.com\/es\/blog\/woocommerce-zapier\/\">Zapier<\/a>, un agente de IA o un servidor que se comunica a trav\u00e9s del <a href=\"https:\/\/kinsta.com\/es\/blog\/servidor-mcp-api-kinsta\/\">protocolo MCP<\/a>, estas entidades sabr\u00e1n exactamente c\u00f3mo activar operaciones estructuradas en tu sitio.<\/p>\n<h2>C\u00f3mo trabajar con la API Abilities<\/h2>\n<p>La API Abilities ofrece un <a href=\"https:\/\/github.com\/WordPress\/abilities-api\/blob\/trunk\/docs\/php-api.md\">conjunto completo de funciones<\/a> que te permiten detectar las abilities registradas en tu sitio, activarlas, adem\u00e1s de registrarlas y darlas de baja.<br \/>\n<div><\/div><kinsta-auto-toc list-style=\"decimal\" selector=\"h3\" count-number=\"3\" sub-toc=\"true\"><\/kinsta-auto-toc><\/p>\n<h3>Trabaja con las abilities de tu sitio<\/h3>\n<p>Puedes obtener una lista de todas las abilities registradas o recuperar un objeto de una ability concreta. Tambi\u00e9n puedes comprobar ciertas condiciones, como si una ability espec\u00edfica est\u00e1 registrada o si el agente tiene permisos para activarla.<br \/>\n<div><\/div><kinsta-auto-toc list-style=\"decimal\" selector=\"h4\" count-number=\"4\" sub-toc=\"true\"><\/kinsta-auto-toc><\/p>\n<h4>Obtener una lista de las capacidades registradas en tu sitio<\/h4>\n<p><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_get_abilities\/\" target=\"_blank\" rel=\"noopener noreferrer\">La funci\u00f3n <code>wp_get_abilities()<\/code><\/a> devuelve una array con todas las abilities registradas. Puedes probarla usando <a href=\"https:\/\/kinsta.com\/es\/blog\/wp-cli\/\">WP-CLI<\/a>. Una vez que te <a href=\"https:\/\/kinsta.com\/es\/blog\/desarrollo-remoto-de-wordpress-en-kinsta-con-ssh\/\">conectes a tu sitio v\u00eda SSH<\/a>, ve al directorio ra\u00edz del sitio, donde est\u00e1 tu <a href=\"https:\/\/kinsta.com\/es\/blog\/wp-config-php\/\">archivo<u><code>wp-config.php<\/code><\/u><\/a>, usando los siguientes comandos:<\/p>\n<pre><code class=\"language-bash\">cd \/path\/to\/your\/site\nls wp-config.php<\/code><\/pre>\n<p>A continuaci\u00f3n, aseg\u00farate de que WP-CLI reconoce la instalaci\u00f3n de tu sitio:<\/p>\n<pre><code class=\"language-bash\">wp core is-installed\nwp option get siteurl<\/code><\/pre>\n<p>Si aparece la URL de tu sitio, ya est\u00e1s listo para ejecutar el siguiente comando:<\/p>\n<pre><code class=\"language-bash\">wp eval '$abilities = wp_get_abilities(); foreach ( $abilities as $a ) { echo $a-&gt;get_name() . PHP_EOL; }'<\/code><\/pre>\n<p>Este comando ejecuta <a href=\"https:\/\/developer.wordpress.org\/cli\/commands\/eval\/\" target=\"_blank\" rel=\"noopener noreferrer\">c\u00f3digo PHP en tu terminal<\/a>. El c\u00f3digo PHP solicita los nombres de todas las abilities registradas en tu sitio y, por defecto, deber\u00eda dar la siguiente respuesta:<\/p>\n<pre><code class=\"language-bash\">core\/get-site-info\ncore\/get-user-info\ncore\/get-environment-info<\/code><\/pre>\n<p>Puedes solicitar un conjunto de datos m\u00e1s completo con el siguiente comando:<\/p>\n<pre><code class=\"language-bash\">wp eval '\n$all_abilities = wp_get_abilities();\n\nforeach ( $all_abilities as $ability ) {\n\techo \"Ability Name: \" . esc_html( $ability-&gt;get_name() ) . \"\\n\";\n\techo \"Label: \" . esc_html( $ability-&gt;get_label() ) . \"\\n\";\n\techo \"Category: \" . esc_html( $ability-&gt;get_category() ) . \"\\n\";\n\techo \"Description: \" . esc_html( $ability-&gt;get_description() ) . \"\\n\";\n\techo \"---\\n\";\n}\n'<\/code><\/pre>\n<p>Cuando ejecutes este comando en un sitio nuevo de <a href=\"https:\/\/kinsta.com\/es\/blog\/wordpress-7-0\/\">WordPress 7.0<\/a>, la terminal mostrar\u00e1 la siguiente respuesta:<\/p>\n<pre><code>Ability Name: core\/get-site-info\nLabel: Get Site Information\nCategory: site\nDescription: Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.\n---\nAbility Name: core\/get-user-info\nLabel: Get User Information\nCategory: user\nDescription: Returns profile details for the current authenticated user to support personalization, auditing, and access-aware behavior. By default returns all fields, or optionally a filtered subset.\n---\nAbility Name: core\/get-environment-info\nLabel: Get Environment Info\nCategory: site\nDescription: Returns core details about the site's runtime context for diagnostics and compatibility (environment, PHP runtime, database server info, WordPress version). By default returns all fields, or optionally a filtered subset.\n---<\/code><\/pre>\n<h4>Obtener un objeto ability<\/h4>\n<p><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_get_ability\/\" target=\"_blank\" rel=\"noopener noreferrer\">La funci\u00f3n <code>wp_get_ability()<\/code><\/a> devuelve un \u00fanico objeto ability por su nombre. Puedes probarla en WP-CLI con este comando:<\/p>\n<pre><code class=\"language-bash\">wp eval '\n$ability = wp_get_ability( \"core\/get-site-info\" );\n\nif ( ! $ability ) {\n\techo \"Ability not found\\n\";\n\texit( 1 );\n}\n\necho \"Name: \" . $ability-&gt;get_name() . \"\\n\";\necho \"Label: \" . $ability-&gt;get_label() . \"\\n\";\necho \"Category: \" . $ability-&gt;get_category() . \"\\n\";\necho \"Description: \" . $ability-&gt;get_description() . \"\\n\";\necho \"nInput Schema:\\n\";\nvar_dump( $ability-&gt;get_input_schema() );\necho \"nOutput Schema:\\n\";\nvar_dump( $ability-&gt;get_output_schema() );\necho \"nMeta:\\n\";\nvar_dump( $ability-&gt;get_meta() );\n'<\/code><\/pre>\n<p>Si la ability est\u00e1 correctamente registrada en tu sitio, recibir\u00e1s la siguiente respuesta en tu terminal:<\/p>\n<pre><code>Name: core\/get-site-info\nLabel: Get Site Information\nCategory: site\nDescription: Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.\n\nInput Schema:\narray(4) {\n  [\"type\"]=&gt;\n  string(6) \"object\"\n  [\"properties\"]=&gt;\n  array(1) {\n\t[\"fields\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(5) \"array\"\n\t  [\"items\"]=&gt;\n\t  array(2) {\n\t\t[\"type\"]=&gt;\n\t\tstring(6) \"string\"\n\t\t[\"enum\"]=&gt;\n\t\tarray(8) {\n\t\t  [0]=&gt;\n\t\t  string(4) \"name\"\n\t\t  [1]=&gt;\n\t\t  string(11) \"description\"\n\t\t  [2]=&gt;\n\t\t  string(3) \"url\"\n\t\t  [3]=&gt;\n\t\t  string(5) \"wpurl\"\n\t\t  [4]=&gt;\n\t\t  string(11) \"admin_email\"\n\t\t  [5]=&gt;\n\t\t  string(7) \"charset\"\n\t\t  [6]=&gt;\n\t\t  string(8) \"language\"\n\t\t  [7]=&gt;\n\t\t  string(7) \"version\"\n\t\t}\n\t  }\n\t  [\"description\"]=&gt;\n\t  string(81) \"Optional: Limit response to specific fields. If omitted, all fields are returned.\"\n\t}\n  }\n  [\"additionalProperties\"]=&gt;\n  bool(false)\n  [\"default\"]=&gt;\n  array(0) {\n  }\n}\n\nOutput Schema:\narray(3) {\n  [\"type\"]=&gt;\n  string(6) \"object\"\n  [\"properties\"]=&gt;\n  array(8) {\n\t[\"name\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(10) \"Site Title\"\n\t  [\"description\"]=&gt;\n\t  string(15) \"The site title.\"\n\t}\n\t[\"description\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(7) \"Tagline\"\n\t  [\"description\"]=&gt;\n\t  string(17) \"The site tagline.\"\n\t}\n\t[\"url\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(18) \"Site Address (URL)\"\n\t  [\"description\"]=&gt;\n\t  string(94) \"The public URL where visitors access the site. May differ from the WordPress installation URL.\"\n\t}\n\t[\"wpurl\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(23) \"WordPress Address (URL)\"\n\t  [\"description\"]=&gt;\n\t  string(83) \"The URL where WordPress core files are served. May differ from the public site URL.\"\n\t}\n\t[\"admin_email\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(28) \"Administration Email Address\"\n\t  [\"description\"]=&gt;\n\t  string(37) \"The site administrator email address.\"\n\t}\n\t[\"charset\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(12) \"Site Charset\"\n\t  [\"description\"]=&gt;\n\t  string(28) \"The site character encoding.\"\n\t}\n\t[\"language\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(13) \"Site Language\"\n\t  [\"description\"]=&gt;\n\t  string(42) \"The site locale in dash form (e.g. en-US).\"\n\t}\n\t[\"version\"]=&gt;\n\tarray(3) {\n\t  [\"type\"]=&gt;\n\t  string(6) \"string\"\n\t  [\"title\"]=&gt;\n\t  string(17) \"WordPress Version\"\n\t  [\"description\"]=&gt;\n\t  string(48) \"The WordPress core version running on this site.\"\n\t}\n  }\n  [\"additionalProperties\"]=&gt;\n  bool(false)\n}\n\nMeta:\narray(2) {\n  [\"annotations\"]=&gt;\n  array(3) {\n\t[\"readonly\"]=&gt;\n\tbool(true)\n\t[\"destructive\"]=&gt;\n\tbool(false)\n\t[\"idempotent\"]=&gt;\n\tbool(true)\n  }\n  [\"show_in_rest\"]=&gt;\n  bool(true)\n}<\/code><\/pre>\n<h4>Comprobar si una ability est\u00e1 registrada<\/h4>\n<p><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_has_ability\/\" target=\"_blank\" rel=\"noopener noreferrer\">La funci\u00f3n <code>wp_has_ability()<\/code><\/a> te permite comprobar si una ability est\u00e1 registrada. En WP-CLI, puedes usarla as\u00ed:<\/p>\n<pre><code class=\"language-bash\">wp eval '\nif ( wp_has_ability( \"core\/get-site-info\" ) ) {\n\techo \"\u2713 core\/get-site-info is registered\\n\";\n} else {\n\techo \"\u2717 core\/get-site-info not found\\n\";\n}\n'<\/code><\/pre>\n<p>Si la ability est\u00e1 registrada, aparecer\u00e1 el siguiente mensaje en la terminal:<\/p>\n<pre><code class=\"language-bash\">\u2713 core\/get-site-info is registered<\/code><\/pre>\n<h4>Comprobar los permisos del agente<\/h4>\n<p>Puedes comprobar si el usuario actual tiene permisos para ejecutar una ability utilizando el <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_ability\/check_permissions\/\" target=\"_blank\" rel=\"noopener noreferrer\">m\u00e9todo <code>check_permissions()<\/code><\/a> del objeto <code>$ability<\/code>. Este m\u00e9todo devuelve true, false o un objeto <code>WP_Error<\/code>. Intentemos llamar a este m\u00e9todo desde la terminal con el siguiente comando de WP-CLI:<\/p>\n<pre><code class=\"language-bash\">wp --user=1 eval '\n$ability = wp_get_ability( \"core\/get-site-info\" );\nif ( $ability ) {\n\t$has_permissions = $ability-&gt;check_permissions();\n\tif ( true === $has_permissions ) {\n\t\techo \"You have permissions to execute this ability.\";\n\t} else {\n\t\tif ( is_wp_error( $has_permissions ) ) {\n\t\t\terror_log( \"Permissions check failed: \" . $has_permissions-&gt;get_error_message() );\n\t\t}\n\t\techo \"You do not have permissions to execute this ability.\";\n\t}\n} else {\n\techo \"Ability not found.\";\n}\n'<\/code><\/pre>\n<p>Aqu\u00ed hemos establecido <code>--user=1<\/code>, por lo que recibir\u00e1s la siguiente respuesta:<\/p>\n<pre><code class=\"language-bash\">You have permissions to execute this ability.<\/code><\/pre>\n<h3>Registrar una ability<\/h3>\n<p>Ahora es el momento de registrar una ability. Para mostrar un caso de uso real, vamos a ampliar el plugin que describimos en <a href=\"https:\/\/kinsta.com\/es\/blog\/ia-wordpress\/\">nuestro art\u00edculo sobre Clientes de IA de WordPress<\/a>. El plugin env\u00eda un archivo de audio al modelo de IA para extraer el texto y activar la generaci\u00f3n de bloques de Gutenberg. En esta secci\u00f3n, veremos c\u00f3mo registrar este proceso como una ability para que cualquier entidad con los permisos necesarios pueda descubrirla y utilizarla.<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>En los ejemplos que vienen a continuaci\u00f3n, solo mostramos el c\u00f3digo esencial. Para que pruebes por ti mismo el c\u00f3digo que te ofrecemos en esta secci\u00f3n, te recomendamos que descargues el plugin <a href=\"https:\/\/github.com\/carlodaniele\/ai-content-builder-next\" target=\"_blank\" rel=\"noopener noreferrer\">AI Content Builder Next<\/a> de GitHub y lo instales manualmente en un sitio de WordPress local o staging.<\/p>\n<\/aside>\n\n<p>Antes de registrar una nueva ability, tienes que registrar una nueva categor\u00eda de ability.<\/p>\n<p>Para ello, tendr\u00e1s que conectar la <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_ability_category\/\" target=\"_blank\" rel=\"noopener noreferrer\">funci\u00f3n <code>wp_register_ability_category()<\/code><\/a> al hook <code>wp_abilities_api_categories_init<\/code>.<\/p>\n<p>La funci\u00f3n acepta un slug de categor\u00eda \u00fanico y un array asociativo de argumentos.<\/p>\n<p>A continuaci\u00f3n te explicamos c\u00f3mo registrar tu categor\u00eda de ability:<\/p>\n<pre><code class=\"language-php\">function aicb_register_ability_category(): void {\n\n\tif ( ! function_exists( 'wp_register_ability_category' ) ) {\n\t\treturn;\n\t}\n\n\twp_register_ability_category(\n\t\t'content-generation',\n\t\tarray(\n\t\t\t'label'       =&gt; 'Content Generation',\n\t\t\t'description' =&gt; 'AI-powered content transformation and structuring abilities',\n\t\t)\n\t);\n}\nadd_action( 'wp_abilities_api_categories_init', 'aicb_register_ability_category' );<\/code><\/pre>\n<p>El siguiente paso es registrar la ability. Para ello, tendr\u00e1s que conectar la <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_ability\/\" target=\"_blank\" rel=\"noopener noreferrer\">funci\u00f3n <code>wp_register_ability()<\/code><\/a> a la acci\u00f3n <code>wp_abilities_api_init<\/code>.<\/p>\n<p>La funci\u00f3n acepta dos argumentos: el nombre de la ability, incluyendo su espacio de nombres, y un array de argumentos para la configuraci\u00f3n de la ability.<\/p>\n<p>Aqu\u00ed tienes el registro de la ability para el <a href=\"https:\/\/github.com\/carlodaniele\/ai-content-builder-next\/blob\/main\/abilities.php\" target=\"_blank\" rel=\"noopener noreferrer\">plugin AI Content Builder<\/a>:<\/p>\n<pre><code class=\"language-php\">function aicb_register_audio_to_gutenberg_blocks_ability(): void {\n\n\tif ( ! function_exists( 'wp_register_ability' ) ) {\n\t\treturn;\n\t}\n\n\t$input_schema = array( ... );\n\n\t$output_schema = array( ... );\n\n\twp_register_ability(\n\t\t'ai-content-builder\/audio-to-gutenberg-blocks',\n\t\tarray(\n\t\t\t'category'            =&gt; 'content-generation',\n\t\t\t'label'               =&gt; 'Audio to Gutenberg Blocks',\n\t\t\t'description'         =&gt; 'Transcribes audio and converts the content into WordPress Gutenberg-compatible block objects.',\n\t\t\t'input_schema'        =&gt; $input_schema,\n\t\t\t'output_schema'       =&gt; $output_schema,\n\t\t\t'execute_callback'    =&gt; 'aicb_audio_to_gutenberg_blocks_callback',\n\t\t\t'permission_callback' =&gt; static function (): bool {\n\t\t\t\treturn current_user_can( 'edit_posts' );\n\t\t\t},\n\t\t\t'meta'                =&gt; array(\n\t\t\t\t'show_in_rest' =&gt; true,\n\t\t\t\t'annotations'  =&gt; array(\n\t\t\t\t\t'readonly'     =&gt; false,\n\t\t\t\t\t'destructive'  =&gt; false,\n\t\t\t\t\t'idempotent'   =&gt; false,\n\t\t\t\t\t'instructions' =&gt; 'Processes an audio attachment: transcribes it, generates structured blog content via AI, and returns Gutenberg-ready block objects.',\n\t\t\t\t),\n\t\t\t),\n\t\t)\n\t);\n}\nadd_action( 'wp_abilities_api_init', 'aicb_register_audio_to_gutenberg_blocks_ability' );<\/code><\/pre>\n<p>En la llamada a la funci\u00f3n <code>wp_register_ability<\/code>, hemos configurado los siguientes argumentos:<\/p>\n<ul>\n<li><code>category<\/code>: La categor\u00eda a la que pertenece la ability.<\/li>\n<li><code>label<\/code>: El nombre que se muestra de la ability.<\/li>\n<li><code>description<\/code>: Una breve descripci\u00f3n de lo que hace la ability y para qu\u00e9 sirve.<\/li>\n<li><code>input_schema<\/code>: El esquema de datos para los argumentos de entrada.<\/li>\n<li><code>output_schema<\/code>: El esquema de datos que proporciona y devuelve la ability.<\/li>\n<li><code>execute_callback<\/code>: La funci\u00f3n callback que se ejecutar\u00e1 cuando se active la ability.<\/li>\n<li><code>permission_callback<\/code>: Una funci\u00f3n callback que se ejecuta para comprobar que el agente tiene los permisos necesarios para ejecutar la ability.<\/li>\n<li><code>meta<\/code>: Un array de campos de metadatos adicionales para la capacidad.<\/li>\n<li><code>show_in_rest<\/code>: Determina si se muestra o no la funci\u00f3n dentro de la API REST de WordPress.<\/li>\n<li><code>annotations<\/code>: Un array de elementos descriptivos que definen el comportamiento de la ability.<\/li>\n<\/ul>\n<p><code>input_schema<\/code> es un array que define el contrato de entrada de la ability. Representa la definici\u00f3n del esquema JSON para validar la entrada de la ability. En nuestro caso concreto, se define as\u00ed:<\/p>\n<pre><code class=\"language-php\">$input_schema = array(\n\t'type'       =&gt; 'object',\n\t'properties' =&gt; array(\n\t\t'audio_id' =&gt; array(\n\t\t\t'type'        =&gt; 'integer',\n\t\t\t'description' =&gt; 'The ID of the audio attachment to process and convert into Gutenberg blocks.',\n\t\t),\n\t),\n\t'required'   =&gt; array( 'audio_id' ),\n);<\/code><\/pre>\n<p>Este esquema JSON representa el formato que deben seguir los datos de entrada para utilizar esta funci\u00f3n.<\/p>\n<p><code>output_schema<\/code> es el contrato de salida que devuelve la funci\u00f3n. En nuestro ejemplo, cada elemento es un objeto que representa un bloque JSON:<\/p>\n<pre><code class=\"language-php\">$output_schema = array(\n\t'type'       =&gt; 'object',\n\t'properties' =&gt; array(\n\t\t'title'      =&gt; array( 'type' =&gt; 'string' ),\n\t\t'sections'   =&gt; array(\n\t\t\t'type'  =&gt; 'array',\n\t\t\t'items' =&gt; array( 'type' =&gt; 'object' ),\n\t\t),\n\t\t'blocks'     =&gt; array(\n\t\t\t'type'  =&gt; 'array',\n\t\t\t'items' =&gt; array( 'type' =&gt; 'object' ),\n\t\t),\n\t\t'transcript' =&gt; array( 'type' =&gt; 'string' ),\n\t),\n\t'required'   =&gt; array( 'blocks' ),\n);<\/code><\/pre>\n<p>El siguiente paso es definir la funci\u00f3n de callback que se ejecuta cuando se activa la capacidad (mira el <a href=\"https:\/\/github.com\/carlodaniele\/ai-content-builder-next\/blob\/main\/abilities.php#L483\" target=\"_blank\" rel=\"noopener noreferrer\">c\u00f3digo completo en GitHub<\/a>):<\/p>\n<pre><code class=\"language-php\">function aicb_audio_to_gutenberg_blocks_callback( array $args ) {\n\n\t\/\/ missing code\n\t\/\/ see GitHub\n\t...\n\n\t$structured_json = wp_ai_client_prompt( $prompt )\n\t\t-&gt;using_system_instruction( $instructions )\n\t\t-&gt;using_temperature( 0.4 )\n\t\t-&gt;as_json_response( $schema )\n\t\t-&gt;generate_text();\n\n\tif ( is_wp_error( $structured_json ) ) {\n\t\treturn $structured_json;\n\t}\n\n\t$structured = json_decode( (string) $structured_json, true );\n\tif ( ! is_array( $structured ) ) {\n\t\treturn new WP_Error(\n\t\t\t'invalid_ai_json',\n\t\t\t'Could not parse structured AI response.',\n\t\t\tarray( 'status' =&gt; 500 )\n\t\t);\n\t}\n\n\t\/\/ Normalize the output.\n\t$normalized = aicb_normalize_structured_post( $structured );\n\n\tif ( '' === $normalized['title'] && empty( $normalized['sections'] ) ) {\n\t\treturn new WP_Error(\n\t\t\t'empty_structured_content',\n\t\t\t'The AI provider returned empty structured content.',\n\t\t\tarray( 'status' =&gt; 500 )\n\t\t);\n\t}\n\n\t\/\/ Convert to Gutenberg blocks.\n\t$blocks = aicb_sections_to_blocks( $normalized['title'], $normalized['sections'] );\n\n\treturn $blocks;\n}<\/code><\/pre>\n<p>Esta funci\u00f3n invoca dos funciones personalizadas. La primera (<code>aicb_normalize_structured_post<\/code>) normaliza la salida de la IA a un formato predefinido y limpia los datos:<\/p>\n<pre><code class=\"language-php\">function aicb_normalize_structured_post( array $structured ): array {\n\t$title = isset( $structured['title'] )\n\t\t? sanitize_text_field( (string) $structured['title'] )\n\t\t: '';\n\n\t$sections = array();\n\n\tif ( isset( $structured['sections'] ) && is_array( $structured['sections'] ) ) {\n\t\tforeach ( $structured['sections'] as $section ) {\n\t\t\tif ( ! is_array( $section ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t$heading = isset( $section['heading'] )\n\t\t\t\t? sanitize_text_field( (string) $section['heading'] )\n\t\t\t\t: '';\n\n\t\t\t$level = 2;\n\n\t\t\t$paragraphs = array();\n\t\t\tif ( isset( $section['paragraphs'] ) && is_array( $section['paragraphs'] ) ) {\n\t\t\t\tforeach ( $section['paragraphs'] as $paragraph ) {\n\t\t\t\t\t$clean_paragraph = trim( sanitize_textarea_field( (string) $paragraph ) );\n\t\t\t\t\tif ( '' !== $clean_paragraph ) {\n\t\t\t\t\t\t$paragraphs[] = $clean_paragraph;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$bullet_points = array();\n\t\t\tif ( isset( $section['bullet_points'] ) && is_array( $section['bullet_points'] ) ) {\n\t\t\t\tforeach ( $section['bullet_points'] as $bullet_point ) {\n\t\t\t\t\t$clean_bullet_point = trim( sanitize_text_field( (string) $bullet_point ) );\n\t\t\t\t\tif ( '' !== $clean_bullet_point ) {\n\t\t\t\t\t\t$bullet_points[] = $clean_bullet_point;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( '' === $heading || empty( $paragraphs ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t$sections[] = array(\n\t\t\t\t'heading'       =&gt; $heading,\n\t\t\t\t'level'         =&gt; $level,\n\t\t\t\t'paragraphs'    =&gt; $paragraphs,\n\t\t\t\t'bullet_points' =&gt; $bullet_points,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn array(\n\t\t'title'    =&gt; $title,\n\t\t'sections' =&gt; $sections,\n\t);\n}<\/code><\/pre>\n<p>La funci\u00f3n acepta un array estructurado de objetos JSON, normaliza y depura los datos, y devuelve una array que contiene el t\u00edtulo y las secciones.<\/p>\n<p>La segunda funci\u00f3n (<code>aicb_sections_to_blocks<\/code>) convierte los datos normalizados en objetos descriptores de bloques y se define as\u00ed:<\/p>\n<pre><code class=\"language-php\">function aicb_sections_to_blocks( string $title, array $sections ): array {\n\t$blocks = array();\n\n\tforeach ( $sections as $section ) {\n\t\tif ( ! is_array( $section ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t$heading = isset( $section['heading'] ) ? trim( (string) $section['heading'] ) : '';\n\t\tif ( '' === $heading ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t$paragraphs = array();\n\t\tif ( isset( $section['paragraphs'] ) && is_array( $section['paragraphs'] ) ) {\n\t\t\tforeach ( $section['paragraphs'] as $paragraph ) {\n\t\t\t\t$clean = trim( (string) $paragraph );\n\t\t\t\tif ( '' !== $clean ) {\n\t\t\t\t\t$paragraphs[] = $clean;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( empty( $paragraphs ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t$blocks[] = array(\n\t\t\t'name'       =&gt; 'core\/heading',\n\t\t\t'attributes' =&gt; array(\n\t\t\t\t'content' =&gt; $heading,\n\t\t\t\t'level'   =&gt; 2,\n\t\t\t),\n\t\t);\n\n\t\tforeach ( $paragraphs as $paragraph ) {\n\t\t\t$blocks[] = array(\n\t\t\t\t'name'       =&gt; 'core\/paragraph',\n\t\t\t\t'attributes' =&gt; array(\n\t\t\t\t\t'content' =&gt; $paragraph,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif ( isset( $section['bullet_points'] ) && is_array( $section['bullet_points'] ) ) {\n\t\t\t$bullet_items_html = '';\n\n\t\t\tforeach ( $section['bullet_points'] as $bullet_point ) {\n\t\t\t\t$clean_bullet = trim( sanitize_text_field( (string) $bullet_point ) );\n\t\t\t\tif ( '' === $clean_bullet ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t\/\/ core\/list expects HTML in the `values` attribute.\n\t\t\t\t$bullet_items_html .= '&lt;li&gt;' . esc_html( $clean_bullet ) . '&lt;\/li&gt;';\n\t\t\t}\n\n\t\t\tif ( '' !== $bullet_items_html ) {\n\t\t\t\t$blocks[] = array(\n\t\t\t\t\t'name'       =&gt; 'core\/list',\n\t\t\t\t\t'attributes' =&gt; array(\n\t\t\t\t\t\t'values' =&gt; '&lt;ul&gt;' . $bullet_items_html . '&lt;\/ul&gt;',\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn $blocks;\n}<\/code><\/pre>\n<p>Estos son los puntos clave de esta funci\u00f3n:<\/p>\n<ul>\n<li>La funci\u00f3n acepta dos argumentos: una cadena que representa el t\u00edtulo de la publicaci\u00f3n y un array con las secciones generadas por el modelo de IA.<\/li>\n<li>Para cada secci\u00f3n, la funci\u00f3n genera un encabezado y al menos un p\u00e1rrafo.<\/li>\n<li>Si hay vi\u00f1etas, genera el n\u00famero correspondiente de elementos de la lista.<\/li>\n<li>La funci\u00f3n devuelve un array <code>$blocks<\/code> de objetos descriptores de bloques, que es el contrato de salida que devuelve la ability (<code>$output_schema<\/code>).<\/li>\n<\/ul>\n<p>Ten en cuenta que el resultado de la funci\u00f3n no es el c\u00f3digo de marcado del bloque sin procesar. Este se generar\u00e1 en el lado del cliente mediante la funci\u00f3n <code>createBlock<\/code> de JavaScript.<\/p>\n<p>Por ejemplo, el elemento de t\u00edtulo de una secci\u00f3n se representa mediante el siguiente objeto:<\/p>\n<pre><code class=\"language-php\">if ( '' !== $heading ) {\n\t$blocks[] = array(\n\t\t'name'       =&gt; 'core\/heading',\n\t\t'attributes' =&gt; array(\n\t\t\t'content' =&gt; $heading,\n\t\t\t'level'   =&gt; ( 3 === $level ) ? 3 : 2,\n\t\t),\n\t);\n}<\/code><\/pre>\n<p>Una vez que hayas registrado tu ability, puedes ejecutar en tu terminal los mismos comandos de WP-CLI que has visto antes para obtener los detalles. El siguiente c\u00f3digo generar\u00e1 el esquema de entrada para tu capacidad:<\/p>\n<pre><code class=\"language-bash\">wp --user=1 eval '\n$ability = wp_get_ability( \"ai-content-builder\/audio-to-gutenberg-blocks\" );\n\nif ( ! $ability ) {\n    echo \"Ability not found\\n\";\n    exit( 1 );\n}\n\necho \"Input Schema:\\n\";\nvar_dump( $ability-&gt;get_input_schema() );\n'<\/code><\/pre>\n<p>Este es el resultado en la terminal:<\/p>\n<pre><code>Input Schema:\narray(3) {\n\t[\"type\"]=&gt;\n\tstring(6) \"object\"\n\t[\"properties\"]=&gt;\n\tarray(1) {\n\t\t[\"audio_id\"]=&gt;\n\t\tarray(2) {\n\t\t\t[\"type\"]=&gt;\n\t\t\tstring(7) \"integer\"\n\t\t\t[\"description\"]=&gt;\n\t\t\tstring(76) \"The ID of the audio attachment to process and convert into Gutenberg blocks.\"\n\t\t}\n\t}\n\t[\"required\"]=&gt;\n\tarray(1) {\n\t\t[0]=&gt;\n\t\tstring(8) \"audio_id\"\n\t}\n}<\/code><\/pre>\n<p>Del mismo modo, puedes recuperar el esquema de salida de la ability:<\/p>\n<pre><code class=\"language-bash\">wp --user=1 eval '\n$ability = wp_get_ability( \"ai-content-builder\/audio-to-gutenberg-blocks\" );\n\nif ( ! $ability ) {\n    echo \"Ability not found\\n\";\n    exit( 1 );\n}\n\necho \"Output Schema:\\n\";\nvar_dump( $ability-&gt;get_output_schema() );\n'<\/code><\/pre>\n<p>Tambi\u00e9n puedes mostrar el objeto completo de tu ability con el siguiente comando:<\/p>\n<pre><code class=\"language-bash\">wp eval '\n$ability = wp_get_ability( \"ai-content-builder\/audio-to-gutenberg-blocks\" );\n\nif ( ! $ability ) {\n\techo \"Ability not found\\n\";\n\texit( 1 );\n}\n\necho \"Name: \" . $ability-&gt;get_name() . \"\\n\";\necho \"Label: \" . $ability-&gt;get_label() . \"\\n\";\necho \"Category: \" . $ability-&gt;get_category() . \"\\n\";\necho \"Description: \" . $ability-&gt;get_description() . \"\\n\";\necho \"nInput Schema:\\n\";\nvar_dump( $ability-&gt;get_input_schema() );\necho \"nOutput Schema:\\n\";\nvar_dump( $ability-&gt;get_output_schema() );\n'<\/code><\/pre>\n<h3>Ejecutar una ability<\/h3>\n<p>Para ejecutar una ability, usar\u00e1s el m\u00e9todo <code>execute()<\/code> del objeto <code>$ability<\/code>. Puedes probar a ejecutar el siguiente c\u00f3digo PHP a trav\u00e9s de WP-CLI para activar la capacidad <code>core\/get-site-info<\/code>:<\/p>\n<pre><code class=\"language-bash\">wp --user=1 eval '\n$ability = wp_get_ability( \"core\/get-site-info\" );\n\nif ( ! $ability ) {\n\techo \"Ability not found\\n\";\n\texit(1);\n}\n\n$result = $ability-&gt;execute();\n\nif ( is_wp_error( $result ) ) {\n\techo \"ERROR: \" . $result-&gt;get_error_message() . \"\\n\";\n\texit(1);\n}\n\necho json_encode( $result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . \"\\\\n\";\n'<\/code><\/pre>\n<p>Cuando ejecutes este comando, la ability te proporcionar\u00e1 un objeto JSON similar al siguiente:<\/p>\n<pre><code>{\n\t\"name\": \"WordPress 7.0\",\n\t\"description\": \"\",\n\t\"url\": \"http:\/\/yoursite.kinsta.cloud\",\n\t\"wpurl\": \"http:\/\/yoursite.kinsta.cloud\",\n\t\"admin_email\": \"yourname@youremail.com\",\n\t\"charset\": \"UTF-8\",\n\t\"language\": \"en-US\",\n\t\"version\": \"7.1-alpha-62550\"\n}<\/code><\/pre>\n<p>Lo anterior es solo un ejemplo sencillo de una ability que te proporciona datos para tu sitio.<\/p>\n<p>Como ya hemos dicho, una ability puede necesitar datos de entrada, realizar operaciones con esos datos y devolver un resultado estructurado. Podemos ver un ejemplo de esto con la ability que registramos en la secci\u00f3n anterior.<\/p>\n<p>Sin salir de tu terminal, ve al directorio ra\u00edz de tu sitio y ejecuta el siguiente c\u00f3digo PHP:<\/p>\n<pre><code class=\"language-bash\">wp --user=1 eval '\n$ability = wp_get_ability( \"ai-content-builder\/audio-to-gutenberg-blocks\" );\n\nif ( ! $ability ) {\n\techo \"Ability not found\\n\";\n\texit( 1 );\n}\n\n$input = array( \"audio_id\" =&gt; 1755 );\n\n$result = $ability-&gt;execute( $input );\n\nif ( is_wp_error( $result ) ) {\n\techo \"ERROR: \" . $result-&gt;get_error_message() . \"\\n\";\n\texit( 1 );\n}\n\necho json_encode( $result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . \"\\n\";\n'<\/code><\/pre>\n<p>El m\u00e9todo <code>execute<\/code> pasa los datos de entrada estructurados a la ability, que devuelve un array de objetos listos para convertirse en bloques de Gutenberg:<\/p>\n<pre><code>[\n\t{\n\t\t\"name\": \"core\/heading\",\n\t\t\"attributes\": {\n\t\t\t\"content\": \"A Well-Deserved Rest Day in Marrakech\",\n\t\t\t\"level\": 2\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"core\/paragraph\",\n\t\t\"attributes\": {\n\t\t\t\"content\": \"On April 24th, our group of seven motorcyclists took a break from the open road...\"\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"core\/heading\",\n\t\t\"attributes\": {\n\t\t\t\"content\": \"Exploring Jemaa el-Fnaa and the Medina\",\n\t\t\t\"level\": 2\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"core\/paragraph\",\n\t\t\"attributes\": {\n\t\t\t\"content\": \"Our journey led us straight to Jemaa el-Fnaa, the legendary main square of Marrakech...\"\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"core\/list\",\n\t\t\"attributes\": {\n\t\t\t\"values\": \"&lt;ul&gt;&lt;li&gt;Navigating the bustling souks and narrow alleys of the ancient Medina.&lt;\/li&gt;&lt;li&gt;Savoring traditional Moroccan and Berber dishes.&lt;\/li&gt;&lt;li&gt;Experiencing the vibrant street performances and food stalls of Jemaa el-Fnaa at night.&lt;\/li&gt;&lt;\/ul&gt;\"\n\t\t}\n\t},\n\t...\n]<\/code><\/pre>\n<h2>Integraci\u00f3n con la API REST<\/h2>\n<p>La API Abilities de WordPress ofrece una estructura de enrutamiento unificada que permite a agentes externos consultar mediante programaci\u00f3n las categor\u00edas de abilities disponibles (<code>\/categories<\/code>), inspeccionar contratos de capacidades espec\u00edficos (<code>\/abilities\/{name}<\/code>) y ejecutar una ability concreta utilizando el endpoint est\u00e1ndar run (<code>\/abilities\/{name}\/run<\/code>).<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>Todas las solicitudes a la API REST de WordPress requieren autenticaci\u00f3n. Para scripts externos o herramientas de terceros, como Postman, usa las <a href=\"https:\/\/developer.wordpress.org\/advanced-administration\/security\/application-passwords\/\">contrase\u00f1as de aplicaci\u00f3n de WordPress<\/a>.<\/p>\n<\/aside>\n\n<p>Aqu\u00ed tienes, por ejemplo, una solicitud GET que devuelve la lista de categor\u00edas de nuestro sitio de prueba:<\/p>\n<pre><code>https:\/\/yoursite.kinsta.cloud\/wp-json\/wp-abilities\/v1\/categories<\/code><\/pre>\n<figure id=\"attachment_212438\" aria-describedby=\"caption-attachment-212438\" style=\"width: 1372px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-212438 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/06\/Screenshot-2026-06-26-alle-19.07.03.png\" alt=\"Solicitud GET para las categor\u00edas de abilities en Postman\" width=\"1372\" height=\"496\"><figcaption id=\"caption-attachment-212438\" class=\"wp-caption-text\">Todas las solicitudes deben estar autorizadas<\/figcaption><\/figure>\n<p>Cuando registramos la ability en el ejemplo anterior, establecimos el par\u00e1metro <code>show_in_rest<\/code> en <code>true<\/code>. Al hacerlo, conseguimos que nuestra ability fuera accesible autom\u00e1ticamente a trav\u00e9s de estos endpoints nativos de la API REST de WordPress, dentro del espacio de nombres centralizado del n\u00facleo (<code>wp-abilities\/v1<\/code>).<\/p>\n<p>Esto significa que no hace falta que configures manualmente rutas personalizadas desde cero para invocar una ability desde un entorno externo. Los agentes externos pueden detectar y ejecutar tu funci\u00f3n mediante solicitudes HTTP est\u00e1ndar.<\/p>\n<p>Puedes consultar el contrato espec\u00edfico de nuestra ability con la siguiente solicitud GET:<\/p>\n<pre><code>https:\/\/yoursite.kinsta.cloud\/wp-json\/wp-abilities\/v1\/abilities\/ai-content-builder\/audio-to-gutenberg-blocks<\/code><\/pre>\n<p>Por \u00faltimo, puedes activar la ability con una solicitud POST autenticada:<\/p>\n<pre><code>https:\/\/yoursite.kinsta.cloud\/wp-json\/wp-abilities\/v1\/abilities\/ai-content-builder\/audio-to-gutenberg-blocks\/run<\/code><\/pre>\n<p>Al enviar este tipo de solicitud, aseg\u00farate de haber especificado los datos de entrada. Para nuestro ejemplo, hemos establecido el siguiente JSON en el cuerpo de la solicitud:<\/p>\n<pre><code class=\"language-json\">{\n\t\"input\": {\n\t\t\"audio_id\": YOUR_AUDIO_ID\n\t}\n}<\/code><\/pre>\n<figure id=\"attachment_212446\" aria-describedby=\"caption-attachment-212446\" style=\"width: 1378px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-212446 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/06\/run-ability-via-rest-1.png\" alt=\"Ejecutar una ability mediante una solicitud HTTP en Postman\" width=\"1378\" height=\"1286\"><figcaption id=\"caption-attachment-212446\" class=\"wp-caption-text\">Ejecutar una ability mediante una solicitud HTTP en Postman<\/figcaption><\/figure>\n<p>Nuestra ability proces\u00f3 el audio y lo envi\u00f3 al modelo de IA configurado en el sitio. El modelo devolvi\u00f3 una salida estructurada que posteriormente se normaliz\u00f3 y depur\u00f3, devolviendo finalmente el siguiente array de objetos que contiene los atributos del bloque:<\/p>\n<pre><code class=\"language-json\">{\n\t\"blocks\": [\n\t\t{\n\t\t\t\"name\": \"core\/heading\",\n\t\t\t\"attributes\": { \"content\": \"A Welcome Rest Day in Marrakech\", \"level\": 2 }\n\t\t},\n\t\t{\n\t\t\t\"name\": \"core\/paragraph\",\n\t\t\t\"attributes\": { \"content\": \"On April 24, our group of seven motorcyclists paused our journey...\" }\n\t\t}\n\t]\n}<\/code><\/pre>\n<p>Y este es precisamente el resultado que busc\u00e1bamos.<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>Desde el lanzamiento de WordPress 7.0, la API Abilities tambi\u00e9n est\u00e1 disponible a trav\u00e9s de JavaScript, como resultado de la implementaci\u00f3n de la API Abilities del lado del cliente. Los desarrolladores pueden usar los dos paquetes <code>@wordpress\/abilities<\/code> y <code>@wordpress\/core-abilities<\/code> para registrar abilities \u2014con sus esquemas de entrada y salida, callbacks y anotaciones\u2014 e implementar funcionalidades del lado del cliente. Si quieres un an\u00e1lisis m\u00e1s detallado, echa un vistazo a la nota para desarrolladores sobre la <a href=\"https:\/\/make.wordpress.org\/core\/2026\/03\/24\/client-side-abilities-api-in-wordpress-7-0\/\">API Abilities del lado del cliente<\/a> y a la <a href=\"https:\/\/github.com\/WordPress\/abilities-api\/blob\/trunk\/docs\/javascript-client.md\">documentaci\u00f3n de JavaScript para el lado del cliente<\/a>.<\/p>\n<\/aside>\n\n<h2>El futuro de WordPress es ag\u00e9ntico<\/h2>\n<p>Mientras que el <a href=\"https:\/\/kinsta.com\/es\/blog\/ia-wordpress\/\">Cliente de IA (AI Client) y la nueva arquitectura de conectores<\/a> incorporan capacidades de procesamiento de IA a WordPress, la API Abilities redefine la forma en que WordPress interact\u00faa con el mundo exterior. Estamos viviendo un cambio de paradigma radical, pasando de una arquitectura web tradicional\u2014 basada en la interacci\u00f3n manual del usuario, en la que cada integraci\u00f3n requer\u00eda endpoints personalizados y una asignaci\u00f3n manual\u2014 a una arquitectura basada en la intenci\u00f3n, dise\u00f1ada desde cero para la automatizaci\u00f3n.<\/p>\n<p>Para los desarrolladores de WordPress, la nueva API Abilities supone un punto de inflexi\u00f3n arquitect\u00f3nico, que se caracteriza por desacoplar la funcionalidad de los plugins que contienen su l\u00f3gica, reforzar la seguridad a trav\u00e9s del contrato de entrada\/salida y permitir la interoperabilidad nativa en todo el ecosistema.<\/p>\n<p>En conjunto, estas funcionalidades garantizan que la API Abilities no sea simplemente otra API m\u00e1s, sino un aut\u00e9ntico motor de ejecuci\u00f3n distribuida que te permite vislumbrar un futuro cada vez m\u00e1s aut\u00f3nomo para WordPress.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La API de Abilities, introducida en WordPress 6.9, establece un lenguaje com\u00fan que permite a todos los componentes de WordPress \u2014tanto del n\u00facleo como de los &#8230;<\/p>\n","protected":false},"author":36,"featured_media":84044,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[],"topic":[1270,1345],"class_list":["post-84043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","topic-api","topic-desarrollo-wordpress"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v24.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Primeros pasos con la API Abilities de WordPress: gu\u00eda pr\u00e1ctica<\/title>\n<meta name=\"description\" content=\"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Primeros pasos con la API Abilities de WordPress: Una gu\u00eda pr\u00e1ctica\" \/>\n<meta property=\"og:description\" content=\"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/kinsta.es\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-05T10:01:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-05T12:00:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1470\" \/>\n\t<meta property=\"og:image:height\" content=\"735\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Carlo Daniele\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png\" \/>\n<meta name=\"twitter:creator\" content=\"@carlodaniele\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_ES\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Carlo Daniele\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/\"},\"author\":{\"name\":\"Carlo Daniele\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63\"},\"headline\":\"Primeros pasos con la API Abilities de WordPress: Una gu\u00eda pr\u00e1ctica\",\"datePublished\":\"2026-08-05T10:01:52+00:00\",\"dateModified\":\"2026-08-05T12:00:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/\"},\"wordCount\":2664,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png\",\"inLanguage\":\"es\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/\",\"url\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/\",\"name\":\"Primeros pasos con la API Abilities de WordPress: gu\u00eda pr\u00e1ctica\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png\",\"datePublished\":\"2026-08-05T10:01:52+00:00\",\"dateModified\":\"2026-08-05T12:00:45+00:00\",\"description\":\"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png\",\"width\":1470,\"height\":735},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/es\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"API\",\"item\":\"https:\/\/kinsta.com\/es\/secciones\/api\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Primeros pasos con la API Abilities de WordPress: Una gu\u00eda pr\u00e1ctica\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/es\/#website\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Soluciones de alojamiento premium, r\u00e1pidas y seguras\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/es\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/es\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/kinsta.es\/\",\"https:\/\/x.com\/Kinsta_ES\",\"https:\/\/www.instagram.com\/kinstahosting\/\",\"https:\/\/www.linkedin.com\/company\/kinsta\/\",\"https:\/\/www.pinterest.com\/kinstahosting\/\",\"https:\/\/www.youtube.com\/c\/Kinsta\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63\",\"name\":\"Carlo Daniele\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g\",\"caption\":\"Carlo Daniele\"},\"description\":\"Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.\",\"sameAs\":[\"https:\/\/frammentidicodice.com\/\",\"https:\/\/x.com\/carlodaniele\"],\"url\":\"https:\/\/kinsta.com\/es\/blog\/author\/carlodaniele\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Primeros pasos con la API Abilities de WordPress: gu\u00eda pr\u00e1ctica","description":"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/","og_locale":"es_ES","og_type":"article","og_title":"Primeros pasos con la API Abilities de WordPress: Una gu\u00eda pr\u00e1ctica","og_description":"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.","og_url":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/kinsta.es\/","article_published_time":"2026-08-05T10:01:52+00:00","article_modified_time":"2026-08-05T12:00:45+00:00","og_image":[{"width":1470,"height":735,"url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png","type":"image\/png"}],"author":"Carlo Daniele","twitter_card":"summary_large_image","twitter_description":"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.","twitter_image":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png","twitter_creator":"@carlodaniele","twitter_site":"@Kinsta_ES","twitter_misc":{"Escrito por":"Carlo Daniele","Tiempo de lectura":"23 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/"},"author":{"name":"Carlo Daniele","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63"},"headline":"Primeros pasos con la API Abilities de WordPress: Una gu\u00eda pr\u00e1ctica","datePublished":"2026-08-05T10:01:52+00:00","dateModified":"2026-08-05T12:00:45+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/"},"wordCount":2664,"publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png","inLanguage":"es"},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/","url":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/","name":"Primeros pasos con la API Abilities de WordPress: gu\u00eda pr\u00e1ctica","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png","datePublished":"2026-08-05T10:01:52+00:00","dateModified":"2026-08-05T12:00:45+00:00","description":"Usa la API Abilities de WordPress para transformar tu plugin en servicios seguros, basados en contratos y listos para automatizar con IA.","breadcrumb":{"@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#primaryimage","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2026\/07\/getting-started-with-the-wordpress-abilities-a-i-a-practical-guide.png","width":1470,"height":735},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/es\/blog\/api-abilities-wordpress\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/es\/"},{"@type":"ListItem","position":2,"name":"API","item":"https:\/\/kinsta.com\/es\/secciones\/api\/"},{"@type":"ListItem","position":3,"name":"Primeros pasos con la API Abilities de WordPress: Una gu\u00eda pr\u00e1ctica"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/es\/#website","url":"https:\/\/kinsta.com\/es\/","name":"Kinsta\u00ae","description":"Soluciones de alojamiento premium, r\u00e1pidas y seguras","publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/es\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/kinsta.es\/","https:\/\/x.com\/Kinsta_ES","https:\/\/www.instagram.com\/kinstahosting\/","https:\/\/www.linkedin.com\/company\/kinsta\/","https:\/\/www.pinterest.com\/kinstahosting\/","https:\/\/www.youtube.com\/c\/Kinsta"]},{"@type":"Person","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63","name":"Carlo Daniele","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g","caption":"Carlo Daniele"},"description":"Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.","sameAs":["https:\/\/frammentidicodice.com\/","https:\/\/x.com\/carlodaniele"],"url":"https:\/\/kinsta.com\/es\/blog\/author\/carlodaniele\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/84043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/users\/36"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/comments?post=84043"}],"version-history":[{"count":14,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/84043\/revisions"}],"predecessor-version":[{"id":84186,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/84043\/revisions\/84186"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/84043\/translations\/en"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/84043\/translations\/it"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/84043\/translations\/fr"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/84043\/translations\/de"},{"embeddable":true,"hreflang":"ja","title":"Japanese","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/84043\/translations\/jp"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/84043\/translations\/es"},{"href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/84043\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media\/84044"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media?parent=84043"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/tags?post=84043"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/topic?post=84043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}