{"id":671,"date":"2026-10-29T13:12:30","date_gmt":"2026-10-29T13:12:30","guid":{"rendered":"https:\/\/vectalk.com.br\/blog\/webhooks-api-whatsapp\/"},"modified":"2026-10-29T13:12:39","modified_gmt":"2026-10-29T13:12:39","slug":"webhooks-api-whatsapp","status":"publish","type":"post","link":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/","title":{"rendered":"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica con ejemplos"},"content":{"rendered":"\n<p><em>Actualizado el 29\/10\/2026<\/em><\/p>\n\n\n\n<p>Un webhook de la API de WhatsApp es una URL HTTPS de tu sistema que recibe, por <code>POST<\/code>, cada evento de la cuenta: mensajes recibidos, cambios de estado (<code>sent<\/code>, <code>delivered<\/code>, <code>read<\/code>, <code>failed<\/code>) y alertas de la cuenta. Un endpoint bien hecho valida el origen de la solicitud, responde 200 en pocos segundos, pone el evento en una cola, lo procesa en segundo plano y descarta los duplicados por ID. En la integraci\u00f3n directa con Meta tambi\u00e9n hay un paso de verificaci\u00f3n por <code>GET<\/code>; con Vectalk, la URL se registra por API y recibe el mismo payload que env\u00eda Meta.<\/p>\n\n\n\n<p>Esta gu\u00eda muestra el formato de los eventos, las diferencias entre integrar directo y a trav\u00e9s de Vectalk, y un servidor completo en Node.js y en Python.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3mo funciona el flujo de eventos<\/h2>\n\n\n\n<p>En la integraci\u00f3n directa, Meta llama al endpoint configurado en tu app. Con Vectalk, Meta llama a Vectalk, que reenv\u00eda el evento a todas las URLs activas registradas para esa instancia:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-text\">Directo:  Meta  \u2500\u2500POST\u2500\u2500\u25b6  tu endpoint\nVectalk:  Meta  \u2500\u2500POST\u2500\u2500\u25b6  Vectalk  \u2500\u2500POST\u2500\u2500\u25b6  tus URLs (una o varias)<\/code><\/pre>\n\n\n\n<p>El cuerpo es el mismo en los dos casos. Lo que cambia es c\u00f3mo se registra la URL y c\u00f3mo se autentica la solicitud.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Aspecto<\/th><th>Cloud API directa<\/th><th>Vectalk<\/th><\/tr><\/thead><tbody><tr><td>Registro de la URL<\/td><td>Panel de apps &gt; WhatsApp &gt; Configuraci\u00f3n<\/td><td><code>POST \/api\/webhooks<\/code> con <code>instance_id<\/code>, <code>url<\/code> y <code>name<\/code><\/td><\/tr><tr><td>Verificaci\u00f3n del endpoint<\/td><td><code>GET<\/code> con <code>hub.mode<\/code>, <code>hub.verify_token<\/code> y <code>hub.challenge<\/code><\/td><td>No descrita en la documentaci\u00f3n de Vectalk<\/td><\/tr><tr><td>Firma<\/td><td>Header <code>X-Hub-Signature-256<\/code> (HMAC-SHA256 con el secreto de la app)<\/td><td>No descrita en la documentaci\u00f3n de Vectalk<\/td><\/tr><tr><td>URLs por cuenta<\/td><td>Un endpoint por app (con reemplazos por cuenta de mensajes o por n\u00famero)<\/td><td>Varias URLs por instancia, todas reciben el mismo evento<\/td><\/tr><tr><td>Tiempo de respuesta<\/td><td>Meta reintenta si no recibe 200<\/td><td>Responder 200 en menos de 20 segundos; si no, Vectalk reenv\u00eda<\/td><\/tr><tr><td>Reintentos<\/td><td>Frecuencia decreciente durante hasta 7 d\u00edas<\/td><td>Reenv\u00edo documentado, sin plazo informado<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Fuentes: <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/webhooks\/overview\" target=\"_blank\" rel=\"noreferrer noopener\">descripci\u00f3n general de webhooks de WhatsApp<\/a>, <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/webhooks\/create-webhook-endpoint\" target=\"_blank\" rel=\"noreferrer noopener\">crear un endpoint de webhook<\/a> y <a href=\"https:\/\/docs.vectalk.com.br\/concepts\/webhooks\">webhooks en la documentaci\u00f3n de Vectalk<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3mo registrar el webhook en Vectalk<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-bash\">curl -X POST https:\/\/apis.vectalk.com.br\/api\/webhooks \\\n  -H \"Authorization: Bearer TU_TOKEN\" \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\n    \"instance_id\": \"TU_INSTANCE_ID\",\n    \"url\": \"https:\/\/miapp.com\/whatsapp\/eventos\",\n    \"name\": \"Producci\u00f3n\"\n  }'<\/code><\/pre>\n\n\n\n<p>La respuesta trae el <code>id<\/code> del webhook y <code>active: true<\/code>. El endpoint de actualizaci\u00f3n recibe ese <code>id<\/code> y te permite cambiar la URL, el nombre o desactivar el webhook (<code>active<\/code>); consulta <a href=\"https:\/\/docs.vectalk.com.br\/api-reference\/webhooks\/register\">Registrar webhook<\/a> y <a href=\"https:\/\/docs.vectalk.com.br\/api-reference\/webhooks\/update\">Actualizar webhook<\/a>. La URL tiene que ser HTTPS.<\/p>\n\n\n\n<p>Tener varias URLs por instancia sirve en dos casos: separar producci\u00f3n y pruebas, y enviar el mismo evento a dos sistemas (el CRM y el data warehouse, por ejemplo) sin armar un reenv\u00edo propio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verificaci\u00f3n del endpoint (integraci\u00f3n directa)<\/h2>\n\n\n\n<p>Cuando configuras el webhook en el panel de apps de Meta (en <strong>WhatsApp &gt; Configuraci\u00f3n<\/strong>, o en <strong>Casos de uso &gt; Personalizar &gt; Configuraci\u00f3n<\/strong> si la app se cre\u00f3 con el caso de uso de WhatsApp), Meta hace un <code>GET<\/code> a tu URL con tres par\u00e1metros:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-text\">GET https:\/\/miapp.com\/whatsapp\/eventos?hub.mode=subscribe&amp;hub.challenge=1158201444&amp;hub.verify_token=mi-token-secreto<\/code><\/pre>\n\n\n\n<p>El endpoint debe comprobar que <code>hub.verify_token<\/code> sea igual al valor que definiste en el panel y devolver <code>hub.challenge<\/code> en el cuerpo, con estado 200. Cualquier otra respuesta hace fallar la verificaci\u00f3n. Meta tambi\u00e9n exige un certificado TLS v\u00e1lido en el endpoint; no acepta certificados autofirmados.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Los payloads que vas a recibir<\/h2>\n\n\n\n<p>Todo evento llega con <code>object: \"whatsapp_business_account\"<\/code> y una lista <code>entry<\/code>. Cada <code>entry<\/code> tiene una lista <code>changes<\/code>, y cada <code>change<\/code> tiene <code>field<\/code> y <code>value<\/code>. Para mensajes y estados, <code>field<\/code> es <code>messages<\/code>. Otros campos suscribibles son, por ejemplo, <code>account_alerts<\/code>, <code>account_update<\/code>, <code>message_template_status_update<\/code>, <code>phone_number_quality_update<\/code> y <code>smb_message_echoes<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Mensaje recibido<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-json\">{\n  \"object\": \"whatsapp_business_account\",\n  \"entry\": [{\n    \"id\": \"WABA_ID\",\n    \"changes\": [{\n      \"field\": \"messages\",\n      \"value\": {\n        \"messaging_product\": \"whatsapp\",\n        \"metadata\": {\n          \"display_phone_number\": \"558430000000\",\n          \"phone_number_id\": \"PHONE_NUMBER_ID\"\n        },\n        \"contacts\": [{\n          \"profile\": { \"name\": \"Jo\u00e3o Silva\" },\n          \"wa_id\": \"5584988888888\",\n          \"user_id\": \"BR.13491208655302741918\"\n        }],\n        \"messages\": [{\n          \"from\": \"5584988888888\",\n          \"from_user_id\": \"BR.13491208655302741918\",\n          \"id\": \"wamid.HBgLNTUx...\",\n          \"timestamp\": \"1760000000\",\n          \"type\": \"text\",\n          \"text\": { \"body\": \"Hola, quiero m\u00e1s informaci\u00f3n\" }\n        }]\n      }\n    }]\n  }]\n}<\/code><\/pre>\n\n\n\n<p>Desde abril de 2026, Meta tambi\u00e9n env\u00eda el <strong>BSUID<\/strong> (ID de usuario con alcance de empresa) en <code>contacts[].user_id<\/code> y <code>messages[].from_user_id<\/code>. El n\u00famero de tel\u00e9fono ya no est\u00e1 garantizado: si el cliente activ\u00f3 un nombre de usuario de WhatsApp y no se cumple ninguna de las condiciones de Meta (un mensaje o llamada intercambiados con ese n\u00famero de la empresa en los \u00faltimos 30 d\u00edas, o que el cliente est\u00e9 en tu libreta de contactos), <code>from<\/code> y <code>wa_id<\/code> se omiten. No uses el tel\u00e9fono como \u00fanica clave del contacto; los detalles est\u00e1n en <a href=\"https:\/\/vectalk.com.br\/blog\/es\/nombres-de-usuario-whatsapp-bsuid\/\">nombres de usuario de WhatsApp y BSUID<\/a>.<\/p>\n\n\n\n<p>El campo <code>type<\/code> indica d\u00f3nde est\u00e1 el contenido. Los m\u00e1s comunes:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><code>type<\/code><\/th><th>D\u00f3nde leer<\/th><\/tr><\/thead><tbody><tr><td><code>text<\/code><\/td><td><code>text.body<\/code><\/td><\/tr><tr><td><code>image<\/code>, <code>video<\/code>, <code>audio<\/code>, <code>document<\/code>, <code>sticker<\/code><\/td><td><code>&lt;tipo&gt;.id<\/code> (descarga por el endpoint de multimedia), <code>caption<\/code>, <code>filename<\/code><\/td><\/tr><tr><td><code>interactive<\/code><\/td><td><code>interactive.button_reply<\/code> o <code>interactive.list_reply<\/code><\/td><\/tr><tr><td><code>location<\/code><\/td><td><code>location.latitude<\/code>, <code>location.longitude<\/code><\/td><\/tr><tr><td><code>reaction<\/code><\/td><td><code>reaction.message_id<\/code>, <code>reaction.emoji<\/code><\/td><\/tr><tr><td><code>order<\/code><\/td><td><code>order.catalog_id<\/code>, <code>order.product_items[]<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Estado de un mensaje enviado<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-json\">{\n  \"object\": \"whatsapp_business_account\",\n  \"entry\": [{\n    \"id\": \"WABA_ID\",\n    \"changes\": [{\n      \"field\": \"messages\",\n      \"value\": {\n        \"messaging_product\": \"whatsapp\",\n        \"metadata\": { \"display_phone_number\": \"558430000000\", \"phone_number_id\": \"PHONE_NUMBER_ID\" },\n        \"statuses\": [{\n          \"id\": \"wamid.HBgLNTUx...\",\n          \"status\": \"delivered\",\n          \"timestamp\": \"1760000010\",\n          \"recipient_id\": \"5584988888888\",\n          \"recipient_user_id\": \"BR.13491208655302741918\",\n          \"pricing\": { \"billable\": true, \"pricing_model\": \"PMP\", \"type\": \"regular\", \"category\": \"utility\" }\n        }]\n      }\n    }]\n  }]\n}<\/code><\/pre>\n\n\n\n<p>El <code>id<\/code> del estado es el <code>wamid<\/code> que recibiste al enviar el mensaje. El campo <code>recipient_user_id<\/code> trae el BSUID del cliente, tanto si enviaste el mensaje al n\u00famero como al BSUID; <code>recipient_id<\/code> (el tel\u00e9fono) se omite cuando enviaste al BSUID y Meta no puede incluir el n\u00famero. Adem\u00e1s de <code>sent<\/code>, <code>delivered<\/code>, <code>read<\/code> y <code>failed<\/code>, existe <code>played<\/code> para mensajes de voz. Cuando <code>status<\/code> es <code>failed<\/code>, el objeto trae <code>errors[]<\/code> con <code>code<\/code>, <code>title<\/code>, <code>message<\/code> y <code>error_data.details<\/code>.<\/p>\n\n\n\n<p>El objeto <code>pricing<\/code> trae <code>category<\/code> (<code>marketing<\/code>, <code>utility<\/code>, <code>authentication<\/code>, <code>service<\/code>, entre otras) y <code>type<\/code>: <code>regular<\/code> para mensajes cobrables, o un tipo gratuito como <code>free_customer_service<\/code> o <code>free_entry_point<\/code>. Desde el 1 de octubre de 2026, las plantillas de utilidad enviadas dentro de la ventana de atenci\u00f3n se cobran, as\u00ed que llegan como <code>regular<\/code> en lugar de <code>free_customer_service<\/code>. Meta anunci\u00f3 que el campo <code>billable<\/code> quedar\u00e1 obsoleto en favor de <code>type<\/code> y <code>category<\/code>. <code>pricing<\/code> llega con el estado <code>sent<\/code> y con uno de <code>delivered<\/code> o <code>read<\/code>, nunca con <code>failed<\/code>. Referencia completa: <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/webhooks\/reference\/messages\/status\" target=\"_blank\" rel=\"noreferrer noopener\">documentaci\u00f3n del webhook de estado<\/a>. Para saber cu\u00e1nto cuesta cada categor\u00eda, consulta <a href=\"https:\/\/vectalk.com.br\/blog\/es\/precio-api-whatsapp-brasil\/\">el precio de la API de WhatsApp en Brasil<\/a> y, para otros mercados, <a href=\"https:\/\/vectalk.com.br\/blog\/es\/precio-api-whatsapp-por-pais\/\">el precio de la API de WhatsApp por pa\u00eds<\/a>. El manejo de estados est\u00e1 explicado a fondo en <a href=\"https:\/\/vectalk.com.br\/blog\/es\/estado-mensaje-webhook-whatsapp\/\">estados de mensaje por webhook en WhatsApp<\/a>.<\/p>\n\n\n\n<p>Un mismo <code>POST<\/code> puede traer varios mensajes o varios estados: seg\u00fan la documentaci\u00f3n de webhooks de Meta, las notificaciones se agrupan con hasta 1.000 actualizaciones por solicitud, aunque el agrupamiento no est\u00e1 garantizado. Recorre las listas en lugar de leer solo el primer elemento.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Buenas pr\u00e1cticas<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Responde 200 r\u00e1pido y procesa despu\u00e9s<\/h3>\n\n\n\n<p>El endpoint no debe llamar a tu base de datos, a la IA ni a otra API antes de responder. Guarda el cuerpo crudo en una cola (Redis, SQS, RabbitMQ, una tabla de eventos) y devuelve 200. Un worker aparte hace el trabajo pesado. Vectalk documenta un l\u00edmite de 20 segundos para la respuesta; mantente muy por debajo.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">S\u00e9 idempotente<\/h3>\n\n\n\n<p>Meta advierte que los reintentos pueden duplicar notificaciones, y un proxy tambi\u00e9n puede reenviar. Usa el <code>id<\/code> del mensaje (o la combinaci\u00f3n <code>id<\/code> + <code>status<\/code>, en el caso de los estados) como clave \u00fanica. Si la clave ya se proces\u00f3, descarta el evento.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Valida la firma<\/h3>\n\n\n\n<p>En la integraci\u00f3n directa, Meta firma cada <code>POST<\/code> con un HMAC-SHA256 del cuerpo, usando el secreto de tu app, y env\u00eda el resultado en el header <code>X-Hub-Signature-256<\/code> con el formato <code>sha256=&lt;hash&gt;<\/code>. Calcula el hash sobre el <strong>cuerpo crudo<\/strong>, antes de cualquier parseo de JSON, y compara en tiempo constante; el paso a paso est\u00e1 en <a href=\"https:\/\/vectalk.com.br\/blog\/es\/validar-firma-webhook-whatsapp\/\">c\u00f3mo validar la firma del webhook de WhatsApp<\/a>. Los webhooks tambi\u00e9n admiten TLS mutuo (mTLS). No dependas solo de una lista de IPs permitidas: Meta cambia sus direcciones IP peri\u00f3dicamente y recomienda mTLS en su lugar.<\/p>\n\n\n\n<p>Con Vectalk, usa el mecanismo de autenticaci\u00f3n que Vectalk indique para las solicitudes reenviadas (consulta la documentaci\u00f3n o la <a href=\"https:\/\/vectalk.com.br\/contato.html\">p\u00e1gina de contacto<\/a>). Mientras eso no est\u00e9 configurado en tu entorno, usa una ruta de URL dif\u00edcil de adivinar, limita el endpoint a HTTPS y no conf\u00edes en el contenido para acciones sensibles sin verificar el <code>phone_number_id<\/code> esperado.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">No dependas del orden<\/h3>\n\n\n\n<p>Por los reintentos, un estado antiguo puede llegar despu\u00e9s de uno m\u00e1s nuevo, y cuando un mensaje se lee enseguida Meta env\u00eda <code>read<\/code> sin webhook de <code>delivered<\/code>. Guarda el estado m\u00e1s avanzado y el <code>timestamp<\/code> de cada etapa, sin retroceder nunca.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prep\u00e1rate para payloads grandes<\/h3>\n\n\n\n<p>Meta informa que los payloads de webhook pueden tener hasta 3 MB. Ajusta el l\u00edmite de cuerpo de tu servidor (el predeterminado de Express es 100 kb).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Monitorea<\/h3>\n\n\n\n<p>Registra cu\u00e1ntos eventos llegan por minuto y cu\u00e1ntos fallan en el worker. Una ca\u00edda brusca de eventos de mensajes suele ser la primera se\u00f1al de un webhook desactivado, un certificado vencido o un n\u00famero desconectado.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ejemplo completo en Node.js (Express)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-js\">import express from 'express'\nimport crypto from 'node:crypto'\nimport { createClient } from 'redis'\n\nconst app = express()\nconst redis = createClient({ url: process.env.REDIS_URL })\nawait redis.connect()\n\nconst VERIFY_TOKEN = process.env.WHATSAPP_VERIFY_TOKEN \/\/ integraci\u00f3n directa\nconst APP_SECRET = process.env.META_APP_SECRET        \/\/ integraci\u00f3n directa\n\n\/\/ Guarda el cuerpo crudo para validar la firma\napp.use('\/whatsapp\/eventos', express.raw({ type: 'application\/json', limit: '3mb' }))\n\n\/\/ Verificaci\u00f3n del endpoint (solo en la integraci\u00f3n directa con Meta)\napp.get('\/whatsapp\/eventos', (req, res) =&gt; {\n  const { 'hub.mode': mode, 'hub.verify_token': token, 'hub.challenge': challenge } = req.query\n  if (mode === 'subscribe' &amp;&amp; token === VERIFY_TOKEN) return res.status(200).send(challenge)\n  return res.sendStatus(403)\n})\n\nfunction firmaValida(req) {\n  const header = req.get('X-Hub-Signature-256') || ''\n  const esperado = 'sha256=' + crypto.createHmac('sha256', APP_SECRET).update(req.body).digest('hex')\n  const a = Buffer.from(header)\n  const b = Buffer.from(esperado)\n  return a.length === b.length &amp;&amp; crypto.timingSafeEqual(a, b)\n}\n\napp.post('\/whatsapp\/eventos', async (req, res) =&gt; {\n  if (APP_SECRET &amp;&amp; !firmaValida(req)) return res.sendStatus(401)\n  await redis.lPush('whatsapp:eventos', req.body.toString('utf8'))\n  res.sendStatus(200)\n})\n\napp.listen(3000)<\/code><\/pre>\n\n\n\n<p>Y el worker, que consume la cola y descarta duplicados:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-js\">\/\/ usa un cliente Redis conectado igual que arriba\nasync function procesar(evento) {\n  for (const entry of evento.entry ?? []) {\n    for (const change of entry.changes ?? []) {\n      const v = change.value ?? {}\n      for (const msg of v.messages ?? []) {\n        const nuevo = await redis.set(`wa:msg:${msg.id}`, '1', { NX: true, EX: 60 * 60 * 24 * 8 })\n        if (!nuevo) continue \/\/ duplicado\n        await tratarMensaje(v.metadata.phone_number_id, msg, v.contacts) \/\/ tu l\u00f3gica de negocio\n      }\n      for (const st of v.statuses ?? []) {\n        const nuevo = await redis.set(`wa:st:${st.id}:${st.status}`, '1', { NX: true, EX: 60 * 60 * 24 * 8 })\n        if (!nuevo) continue\n        await actualizarEstado(st) \/\/ guarda estado, errores y pricing\n      }\n    }\n  }\n}\n\nwhile (true) {\n  const item = await redis.brPop('whatsapp:eventos', 0)\n  try {\n    await procesar(JSON.parse(item.element))\n  } catch (err) {\n    console.error('error al procesar evento', err)\n    await redis.lPush('whatsapp:eventos:error', item.element)\n  }\n}<\/code><\/pre>\n\n\n\n<p>La expiraci\u00f3n de ocho d\u00edas en las claves cubre la ventana de reintentos de Meta, que llega a siete d\u00edas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ejemplo completo en Python (FastAPI)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-python\">import hashlib, hmac, json, os\nimport redis.asyncio as redis\nfrom fastapi import FastAPI, Request, Response\n\napp = FastAPI()\nr = redis.from_url(os.environ[\"REDIS_URL\"])\nVERIFY_TOKEN = os.environ.get(\"WHATSAPP_VERIFY_TOKEN\")  # integraci\u00f3n directa\nAPP_SECRET = os.environ.get(\"META_APP_SECRET\", \"\")      # integraci\u00f3n directa\n\n\n@app.get(\"\/whatsapp\/eventos\")\nasync def verificar(request: Request):\n    q = request.query_params\n    if q.get(\"hub.mode\") == \"subscribe\" and q.get(\"hub.verify_token\") == VERIFY_TOKEN:\n        return Response(content=q.get(\"hub.challenge\", \"\"), media_type=\"text\/plain\")\n    return Response(status_code=403)\n\n\ndef firma_valida(cuerpo: bytes, header: str) -&gt; bool:\n    esperado = \"sha256=\" + hmac.new(APP_SECRET.encode(), cuerpo, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(esperado, header or \"\")\n\n\n@app.post(\"\/whatsapp\/eventos\")\nasync def recibir(request: Request):\n    cuerpo = await request.body()\n    if APP_SECRET and not firma_valida(cuerpo, request.headers.get(\"X-Hub-Signature-256\")):\n        return Response(status_code=401)\n    await r.lpush(\"whatsapp:eventos\", cuerpo)\n    return Response(status_code=200)<\/code><\/pre>\n\n\n\n<p>Worker en Python:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-python\">import asyncio, json, os\nimport redis.asyncio as redis\n\nr = redis.from_url(os.environ[\"REDIS_URL\"])\nOCHO_DIAS = 60 * 60 * 24 * 8\n\n\nasync def procesar(evento: dict):\n    for entry in evento.get(\"entry\", []):\n        for change in entry.get(\"changes\", []):\n            v = change.get(\"value\", {})\n            for msg in v.get(\"messages\", []):\n                if not await r.set(f\"wa:msg:{msg['id']}\", 1, nx=True, ex=OCHO_DIAS):\n                    continue\n                await tratar_mensaje(v[\"metadata\"][\"phone_number_id\"], msg, v.get(\"contacts\", []))\n            for st in v.get(\"statuses\", []):\n                if not await r.set(f\"wa:st:{st['id']}:{st['status']}\", 1, nx=True, ex=OCHO_DIAS):\n                    continue\n                await actualizar_estado(st)\n\n\nasync def main():\n    while True:\n        _, item = await r.brpop(\"whatsapp:eventos\")\n        try:\n            await procesar(json.loads(item))\n        except Exception as exc:\n            print(\"error al procesar evento\", exc)\n            await r.lpush(\"whatsapp:eventos:error\", item)\n\nasyncio.run(main())<\/code><\/pre>\n\n\n\n<p>Las funciones <code>tratar_mensaje<\/code> y <code>actualizar_estado<\/code> (y sus equivalentes en Node) son tu l\u00f3gica de negocio: responder, guardar en el CRM, activar un agente. Dentro de ellas, identifica al contacto por <code>msg.from_user_id<\/code> (o <code>contacts[].user_id<\/code>) y usa <code>msg.from<\/code> solo cuando est\u00e9 presente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Qu\u00e9 hacer con cada tipo de evento en el worker<\/h2>\n\n\n\n<p>Separar el tratamiento por tipo de evento hace que el worker sea m\u00e1s f\u00e1cil de mantener. Una divisi\u00f3n que funciona bien:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Mensajes recibidos<\/strong>: guarda el mensaje, actualiza la hora del \u00faltimo mensaje del contacto (es lo que indica si la ventana de 24 horas est\u00e1 abierta) y reci\u00e9n entonces activa el chatbot, el agente o la cola de atenci\u00f3n humana.<\/li>\n\n\n<li><strong>Estados <code>sent<\/code>, <code>delivered<\/code> y <code>read<\/code><\/strong>: actualiza el registro del mensaje enviado por el <code>wamid<\/code>, guardando la hora de cada etapa. Estos datos alimentan los informes de entrega y lectura.<\/li>\n\n\n<li><strong>Estado <code>failed<\/code><\/strong>: guarda el c\u00f3digo de error y decide la acci\u00f3n. Algunos errores piden un nuevo intento m\u00e1s tarde; otros indican que el env\u00edo no va a funcionar sin un cambio, como una plantilla fuera de la ventana o un n\u00famero inv\u00e1lido. No reenv\u00edes en bucle.<\/li>\n\n\n<li><strong>Otros campos<\/strong> (<code>account_update<\/code>, <code>account_alerts<\/code>, cambios de estado de plantillas): env\u00edalos a un canal de alertas del equipo t\u00e9cnico, porque suelen requerir acci\u00f3n humana.<\/li>\n\n<\/ul>\n\n\n\n<p>Mant\u00e9n tambi\u00e9n una cola de errores, como en los ejemplos. Un evento que fall\u00f3 al procesarse no debe desaparecer: tiene que quedar disponible para reprocesarlo cuando se corrija el bug.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pruebas en local<\/h2>\n\n\n\n<p>Para recibir eventos reales en tu computadora, exp\u00f3n el puerto local con un t\u00fanel HTTPS (ngrok, Cloudflare Tunnel o similar) y registra la URL del t\u00fanel como un webhook adicional de la instancia, con un nombre como &#8220;dev&#8221;. Como Vectalk entrega cada evento a todas las URLs activas, el entorno de desarrollo recibe el mismo tr\u00e1fico que producci\u00f3n sin interferir con ella. Desactiva el webhook de dev cuando termines. El paso a paso completo est\u00e1 en <a href=\"https:\/\/vectalk.com.br\/blog\/es\/probar-webhook-whatsapp-localmente\/\">c\u00f3mo probar el webhook de WhatsApp en local con ngrok<\/a>.<\/p>\n\n\n\n<p>Tambi\u00e9n puedes probar el parser sin tr\u00e1fico real, guardando payloads de ejemplo y envi\u00e1ndolos con <code>curl<\/code> (deja <code>META_APP_SECRET<\/code> sin definir en esta prueba, o firma el cuerpo como se muestra en la gu\u00eda de firma; si no, el servidor responder\u00e1 401):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-bash\">curl -X POST http:\/\/localhost:3000\/whatsapp\/eventos \\\n  -H \"Content-Type: application\/json\" \\\n  --data @ejemplos\/mensaje-texto.json<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Errores comunes<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>S\u00edntoma<\/th><th>Causa probable<\/th><\/tr><\/thead><tbody><tr><td>Mensajes procesados dos veces<\/td><td>Falta deduplicar por <code>id<\/code><\/td><\/tr><tr><td>Eventos que llegan atrasados en r\u00e1faga<\/td><td>Endpoint lento; el origen acumul\u00f3 reintentos<\/td><\/tr><tr><td>La firma nunca coincide<\/td><td>Hash calculado sobre el JSON ya parseado, no sobre el cuerpo crudo<\/td><\/tr><tr><td><code>413 Payload Too Large<\/code><\/td><td>L\u00edmite de cuerpo del servidor por debajo de 3 MB<\/td><\/tr><tr><td>Solo se procesa el primer mensaje del lote<\/td><td>C\u00f3digo que lee <code>messages[0]<\/code> en lugar de recorrer la lista<\/td><\/tr><tr><td>Estado que retrocede de <code>read<\/code> a <code>delivered<\/code><\/td><td>Eventos fuera de orden que sobrescriben el estado<\/td><\/tr><tr><td>Contactos sin tel\u00e9fono en el CRM<\/td><td>C\u00f3digo que usa solo <code>from<\/code>\/<code>wa_id<\/code> e ignora el BSUID<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Preguntas frecuentes<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfTengo que devolver algo en el cuerpo de la respuesta del webhook?<\/h3>\n\n\n\n<p>No. Basta con el estado HTTP 200. El contenido de la respuesta se ignora, excepto en la verificaci\u00f3n por <code>GET<\/code> de la integraci\u00f3n directa, donde el cuerpo debe ser el <code>hub.challenge<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfPuedo usar la misma URL para varios n\u00fameros?<\/h3>\n\n\n\n<p>S\u00ed. Usa <code>metadata.phone_number_id<\/code> para saber a qu\u00e9 n\u00famero pertenece el evento. En Vectalk, cada webhook se registra por instancia, y puedes apuntar varias instancias a la misma URL.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfDurante cu\u00e1nto tiempo Meta intenta reenviar un evento?<\/h3>\n\n\n\n<p>Hasta siete d\u00edas, con frecuencia decreciente, seg\u00fan la documentaci\u00f3n de webhooks de Meta. En Vectalk, la documentaci\u00f3n indica que el evento se reenv\u00eda cuando el endpoint no responde 200 en menos de 20 segundos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfC\u00f3mo recibo los mensajes que el due\u00f1o responde desde la app, con coexistencia?<\/h3>\n\n\n\n<p>Mediante el campo de webhook <code>smb_message_echoes<\/code>. La gu\u00eda de <a href=\"https:\/\/vectalk.com.br\/blog\/es\/coexistencia-api-whatsapp\/\">coexistencia en la API de WhatsApp<\/a> explica los campos adicionales.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Estoy migrando desde Baileys. \u00bfEl formato es muy diferente?<\/h3>\n\n\n\n<p>S\u00ed. Los eventos siguen la estructura <code>entry[].changes[].value<\/code> de Meta, los contactos se identifican por <code>wa_id<\/code> y, desde abril de 2026, tambi\u00e9n por el BSUID (<code>user_id<\/code>), y la multimedia llega por <code>id<\/code>. La gu\u00eda <a href=\"https:\/\/vectalk.com.br\/blog\/es\/migrar-a-api-oficial-de-whatsapp\/\">c\u00f3mo migrar a la API oficial de WhatsApp<\/a> cubre esa transici\u00f3n. Para empezar con Vectalk, crea tu cuenta en <a href=\"https:\/\/apps.vectalk.com.br\/register\">apps.vectalk.com.br\/register<\/a>; las dudas de cuenta van al <a href=\"https:\/\/vectalk.com.br\/ajuda.html\">Centro de Ayuda<\/a> (en portugu\u00e9s).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Fuentes oficiales consultadas el 29\/10\/2026:<\/strong> <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/webhooks\/overview\" target=\"_blank\" rel=\"noreferrer noopener\">Descripci\u00f3n general de webhooks de WhatsApp<\/a>, <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/webhooks\/create-webhook-endpoint\" target=\"_blank\" rel=\"noreferrer noopener\">Crear un endpoint de webhook<\/a>, <a href=\"https:\/\/developers.facebook.com\/docs\/graph-api\/webhooks\/getting-started\" target=\"_blank\" rel=\"noreferrer noopener\">Webhooks de la Graph API: primeros pasos<\/a>, <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/webhooks\/reference\/messages\/status\" target=\"_blank\" rel=\"noreferrer noopener\">Referencia del webhook de estado<\/a>, <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/webhooks\/reference\/messages\/text\" target=\"_blank\" rel=\"noreferrer noopener\">Referencia del webhook de mensaje de texto<\/a>, <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/business-scoped-user-ids\" target=\"_blank\" rel=\"noreferrer noopener\">ID de usuario con alcance de empresa (BSUID)<\/a>, <a href=\"https:\/\/developers.facebook.com\/documentation\/business-messaging\/whatsapp\/pricing\" target=\"_blank\" rel=\"noreferrer noopener\">Precios<\/a>, <a href=\"https:\/\/docs.vectalk.com.br\/concepts\/webhooks\">Webhooks en la documentaci\u00f3n de Vectalk<\/a>, <a href=\"https:\/\/docs.vectalk.com.br\/api-reference\/webhooks\/register\">Registrar webhook (Vectalk)<\/a>, <a href=\"https:\/\/docs.vectalk.com.br\/api-reference\/webhooks\/update\">Actualizar webhook (Vectalk)<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C\u00f3mo funcionan los webhooks de la API de WhatsApp: verificaci\u00f3n, payloads de mensajes y estados, BSUID, firma, colas, reintentos y servidores completos en Node.js y Python.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[12],"tags":[],"class_list":["post-671","post","type-post","status-publish","format-standard","hentry","category-uncategorized-es"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica | Vectalk<\/title>\n<meta name=\"description\" content=\"Webhooks de la API de WhatsApp en la pr\u00e1ctica: verificaci\u00f3n, payloads de mensajes y estados, firma, colas y ejemplos en Node.js y Python.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica | Vectalk\" \/>\n<meta property=\"og:description\" content=\"Webhooks de la API de WhatsApp en la pr\u00e1ctica: verificaci\u00f3n, payloads de mensajes y estados, firma, colas y ejemplos en Node.js y Python.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog Vectalk\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-29T13:12:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-29T13:12:39+00:00\" \/>\n<meta name=\"author\" content=\"wanderleyfcunha\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"wanderleyfcunha\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/\"},\"author\":{\"name\":\"wanderleyfcunha\",\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/#\\\/schema\\\/person\\\/ff36ecd9d8257856f227f8e5d639db2b\"},\"headline\":\"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica con ejemplos\",\"datePublished\":\"2026-10-29T13:12:30+00:00\",\"dateModified\":\"2026-10-29T13:12:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/\"},\"wordCount\":2109,\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/\",\"url\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/\",\"name\":\"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica | Vectalk\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/#website\"},\"datePublished\":\"2026-10-29T13:12:30+00:00\",\"dateModified\":\"2026-10-29T13:12:39+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/#\\\/schema\\\/person\\\/ff36ecd9d8257856f227f8e5d639db2b\"},\"description\":\"Webhooks de la API de WhatsApp en la pr\u00e1ctica: verificaci\u00f3n, payloads de mensajes y estados, firma, colas y ejemplos en Node.js y Python.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/es\\\/webhooks-api-whatsapp\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica con ejemplos\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/\",\"name\":\"Blog Vectalk\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/vectalk.com.br\\\/blog\\\/#\\\/schema\\\/person\\\/ff36ecd9d8257856f227f8e5d639db2b\",\"name\":\"wanderleyfcunha\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/21c37077f1731eb558973f27a7b647d55f72fde5200a843ac5f5345b247ea725?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/21c37077f1731eb558973f27a7b647d55f72fde5200a843ac5f5345b247ea725?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/21c37077f1731eb558973f27a7b647d55f72fde5200a843ac5f5345b247ea725?s=96&d=mm&r=g\",\"caption\":\"wanderleyfcunha\"},\"sameAs\":[\"https:\\\/\\\/vectalk.com.br\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica | Vectalk","description":"Webhooks de la API de WhatsApp en la pr\u00e1ctica: verificaci\u00f3n, payloads de mensajes y estados, firma, colas y ejemplos en Node.js y Python.","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:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/","og_locale":"en_US","og_type":"article","og_title":"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica | Vectalk","og_description":"Webhooks de la API de WhatsApp en la pr\u00e1ctica: verificaci\u00f3n, payloads de mensajes y estados, firma, colas y ejemplos en Node.js y Python.","og_url":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/","og_site_name":"Blog Vectalk","article_published_time":"2026-10-29T13:12:30+00:00","article_modified_time":"2026-10-29T13:12:39+00:00","author":"wanderleyfcunha","twitter_card":"summary_large_image","twitter_misc":{"Written by":"wanderleyfcunha","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/#article","isPartOf":{"@id":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/"},"author":{"name":"wanderleyfcunha","@id":"https:\/\/vectalk.com.br\/blog\/#\/schema\/person\/ff36ecd9d8257856f227f8e5d639db2b"},"headline":"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica con ejemplos","datePublished":"2026-10-29T13:12:30+00:00","dateModified":"2026-10-29T13:12:39+00:00","mainEntityOfPage":{"@id":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/"},"wordCount":2109,"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/","url":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/","name":"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica | Vectalk","isPartOf":{"@id":"https:\/\/vectalk.com.br\/blog\/#website"},"datePublished":"2026-10-29T13:12:30+00:00","dateModified":"2026-10-29T13:12:39+00:00","author":{"@id":"https:\/\/vectalk.com.br\/blog\/#\/schema\/person\/ff36ecd9d8257856f227f8e5d639db2b"},"description":"Webhooks de la API de WhatsApp en la pr\u00e1ctica: verificaci\u00f3n, payloads de mensajes y estados, firma, colas y ejemplos en Node.js y Python.","breadcrumb":{"@id":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/vectalk.com.br\/blog\/es\/webhooks-api-whatsapp\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/vectalk.com.br\/blog\/"},{"@type":"ListItem","position":2,"name":"Webhooks de la API de WhatsApp: gu\u00eda pr\u00e1ctica con ejemplos"}]},{"@type":"WebSite","@id":"https:\/\/vectalk.com.br\/blog\/#website","url":"https:\/\/vectalk.com.br\/blog\/","name":"Blog Vectalk","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/vectalk.com.br\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/vectalk.com.br\/blog\/#\/schema\/person\/ff36ecd9d8257856f227f8e5d639db2b","name":"wanderleyfcunha","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/21c37077f1731eb558973f27a7b647d55f72fde5200a843ac5f5345b247ea725?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/21c37077f1731eb558973f27a7b647d55f72fde5200a843ac5f5345b247ea725?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/21c37077f1731eb558973f27a7b647d55f72fde5200a843ac5f5345b247ea725?s=96&d=mm&r=g","caption":"wanderleyfcunha"},"sameAs":["https:\/\/vectalk.com.br\/blog"]}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/posts\/671","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/comments?post=671"}],"version-history":[{"count":1,"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/posts\/671\/revisions"}],"predecessor-version":[{"id":673,"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/posts\/671\/revisions\/673"}],"wp:attachment":[{"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/media?parent=671"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/categories?post=671"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vectalk.com.br\/blog\/wp-json\/wp\/v2\/tags?post=671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}