Changelog · página 4 de 12

Novedades de la API

Cada cambio de la superficie pública queda registrado aquí, del más nuevo al más viejo. Esta página cubre del 29 ago 2026 – 31 ago 2026. También puedes suscribirte al feed.

v2.47.0 Mejora

Las 328 operaciones ya explican qué hacen

Hasta hoy, 255 de las 328 operaciones públicas traían solo un título de una línea. El resumen te decía qué era la operación, pero no lo que necesitas para llamarla bien: qué devuelve, cuál es el valor por defecto, qué pasa si la repites y con cuál se encadena.

Todas tienen ahora una descripción, y está en el contrato — así que la lee igual tu editor, el SDK y un agente que descubra la API por openapi.json, sin pasar por las guías.

Lo que se documentó es lo que se aprende a golpes:

  • PUT reemplaza y PATCH fusiona. En items, PUT pisa data completo y las claves que no mandes se pierden; PATCH solo toca lo que le pases.
  • Qué es destructivo. Borrar un item o un contacto es definitivo, y borrar un contacto se lleva también sus mensajes. Queda dicho en la operación, no en una nota aparte.
  • Los valores por defecto y los topes, en el mismo lugar donde se eligen: los 50 de una página, los 200 de tope, las 500 filas de un lote de contactos.
  • Cuándo una llamada cambia de forma. POST /runs con stream: true deja de responder JSON y pasa a un stream SSE; el esquema publicado describe el otro caso.
  • Qué te va a bloquear. Un proceso administrado solo acepta activarse o pausarse y no se puede eliminar; un mensaje libre de WhatsApp solo se entrega dentro de la ventana de 24 horas, y fuera de ella hace falta una plantilla.
  • Dónde mirar cuando algo no aparece. El pool de tools de un Met explica por qué el modelo no ve tu Función o tu habilidad, y el log de entregas distingue el evento que nunca salió del que salió y tu servidor rechazó.

No cambia nada de la API. Se conservan las mismas 328 operaciones con sus rutas, parámetros, respuestas y permisos: es el mismo contrato 2.47.0 mejor explicado. No necesitas tocar tus llamadas ni pedir permisos nuevos.

v2.43.0 Cambio

El tipo de campo page se retira del catálogo

page deja de ser un tipo válido en POST /collections/{id}/fields y en PATCH /fields/{id}. El catálogo queda en:

text · number · currency · email · date · datetime · boolean · url
select · prompt · usuario · contact · sitio · image · file

Un campo page guardaba la referencia a una página del módulo Páginas, que se retiró entero. Lo reemplaza Sitios web, que es donde se publica contenido hoy: un campo sitio referencia un sitio y una página sitio se edita en su propio módulo.

Si tenías campos page

Se convirtieron a text conservando el nombre que la página tenía guardado, así que el valor sigue ahí y se puede leer. Lo que ya no hay es la relación: el campo dejó de apuntar a una entidad y pasó a ser una etiqueta.

Si mandas type: "page"

La petición responde 400 con invalid_request_error. No hay ciclo de deprecación porque no queda nada al otro lado de la referencia: el módulo, sus páginas y su vista HTML se fueron en la misma versión.

v2.48.0 Nuevo

Ejecuta una extracción sin herramientas ni contexto del workspace

POST /workspaces/{workspaceId}/runs admite tool_policy: "none" para trabajar únicamente con el input, sus adjuntos y las instrucciones del Met vinculado. No carga skills, integraciones, historial previo, variables ni contexto dinámico del workspace. Si falta un Met válido, falla: no pasa al orquestador. Un intento de invocar herramientas detiene la ejecución sin despacharlas.

Los adjuntos admitidos son PDF e imágenes (native_attachment_kinds: ["pdf", "image"]) mediante URL HTTPS firmada del almacenamiento configurado de Meteor. No consulta la caché de extracción ni OCR. Audio y documentos que necesitan conversión se rechazan antes de crear un run: pega su texto o transcripción como input.

Antes de usar esta política consulta GET /workspaces/{workspaceId}/runs/capabilities con la misma key y workspace. Requiere runs:execute, no ejecuta un Met ni consume Energía, y responde policy_version: 1 y tool_policies: ["none"]. La respuesta no se almacena en caché. Los SDK ofrecen met.runs.capabilities() y conservan tool_policy tanto en ejecución normal como en streaming.

El run conserva metadata.tool_policy: "none" en POST y GET. Verifica también status: "completed" antes de consumir su salida. Omitir la política conserva el comportamiento anterior. Durante un despliegue mixto, el preflight no prueba que otra instancia vaya a atender el POST: activa consumidores solo después de verificar que todas las instancias aplican esta política.

v2.47.0 Corrección

Corrección de los esquemas auxiliares de la referencia de Partners

La definición descargable de Partners y su copia en el portal actualizan sus esquemas auxiliares. Esta corrección documenta el mismo contrato 2.47.0: no es una nueva versión de la API.

Se conservan las mismas 37 operaciones, sus rutas, parámetros, respuestas y requisitos de autenticación. No necesitas cambiar tus llamadas ni solicitar permisos nuevos. La presencia de un esquema auxiliar no habilita una operación adicional con tu key.

v2.47.0 Seguridad

Toda llamada a tu código viene firmada, sin que tengas que configurar nada

Cuando registras tu API como una Función IA de tipo HTTP, el Met la invoca mandándole una petición a tu servidor. Hasta ahora esa petición solo iba firmada si configurabas un secreto a mano, y quien no lo hacía dejaba su endpoint abierto: cualquiera que descubriera la URL podía hacerse pasar por Meteor y disparar tu código con los argumentos que quisiera.

Eso se acabó. Ahora toda llamada saliente va firmada, siempre.

Meteor genera un secreto propio para tu workspace y lo deja en una variable reservada, MET_TOOL_SIGN_SECRET, que ves y cambias desde Variables como cualquier otra. Si ya tenías tu propio secreto configurado en la Función (sign_secret_variable), ese sigue mandando y no cambia nada para ti.

La firma viaja en la cabecera X-Met-Signature, con el mismo esquema de los eventos salientes:

X-Met-Signature: t=<unix_ts>,v1=<hex(hmac_sha256(secreto, "<t>.<cuerpo>"))>

El timestamp va dentro del cálculo, así que una petición vieja no se puede reenviar con una hora nueva. Verifícala con met.tools.createHandler(secreto) del SDK en vez de escribir el HMAC a mano.

Si ya tenías Funciones HTTP registradas, no se rompe nada: reciben una cabecera de más y tu servidor la ignora hasta que decidas verificarla. Te recomendamos que la verifiques, que es justamente lo que esta cabecera te permite hacer.

v2.47.0 Nuevo

Tu aplicación se registra sola para conectarse a Meteor

Hasta ahora, para que una aplicación se conectara a una cuenta de Meteor por OAuth, alguien tenía que entrar a Ajustes → Desarrolladores y crearla a mano. Eso deja por fuera a los clientes que descubren un servidor MCP y esperan poder registrarse solos, que es como funcionan Claude y ChatGPT.

Ya se puede. Meteor implementa registro dinámico de clientes (RFC 7591), y lo anuncia en su documento de descubrimiento como registration_endpoint:

curl -X POST https://api.met.meteor.com.co/oauth/register \
  -H "Content-Type: application/json" \
  -d '{"client_name":"Mi App","redirect_uris":["https://mi-app.com/callback"]}'

Te devuelve client_id y client_secret de una vez, sin sesión y sin intervención de nadie.

Registrarse no da acceso a nada por sí solo: para que exista un token, alguien de la cuenta tiene que iniciar sesión en Meteor y aprobar los permisos. Una app que se registró sola alcanza los permisos del servidor MCP, no todos los de la plataforma, y la pantalla de consentimiento la muestra como no verificada — distinta de una app revisada por Meteor.

Las redirect_uris deben ser https, salvo direcciones locales para aplicaciones de escritorio. No se aceptan comodines.

v2.47.0 Nuevo

Tu agente ya sabe dónde está parado, y encuentra datos sin adivinar

El servidor MCP pasa de 34 a 39 herramientas. La que más cambia el día a día es la primera del catálogo:

met_whoami responde en qué workspace está el agente, si su clave es de prueba y qué permisos trae. Y hace algo que faltaba: le muestra el catálogo completo, incluidas las herramientas que no puede usar, con el motivo de cada ausencia. Antes, una herramienta ausente y una inexistente eran indistinguibles para el agente, así que no tenía forma de saber que le faltaba un permiso ni cuál pedir.

met_search_items busca en tus datos sin conocer de antemano la colección, y pagina. Antes solo se podía recorrer la primera página de una colección conocida.

met_get_contact, met_update_contact y met_list_contact_fields cierran el ciclo del CRM: el agente puede releer la ficha completa de un contacto, guardar lo que averiguó hablando con esa persona, y consultar qué campos personalizados acepta tu cuenta en vez de adivinar los nombres.

Además, cuando una herramienta falla ahora te devuelve un error estructurado —con su código, no una frase suelta— y, en los casos donde reintentar no sirve, te dice qué hacer.

v2.47.0 Nuevo

Reenvía un evento, y cambia el secreto de tu webhook sin perder entregas

Tres cosas que le faltaban a los webhooks salientes.

Reenviar un evento que ya pasó. Si tu servidor estaba caído, o si arreglaste un error y quieres volver a procesar algo, ya no tienes que esperar a que vuelva a ocurrir:

curl -X POST https://api.met.meteor.com.co/api/v1/events/evt_01M106.../replay \
  -H "Authorization: Bearer $MET_API_KEY"

Crea entregas nuevas, no reescribe las viejas, y quedan marcadas como reenvío para que las distingas en la pantalla de entregas. Pide webhooks:manage.

Cambiar el secreto sin perder una sola entrega. Antes, rotar el secreto rompía tu verificación en el instante del cambio. Ahora hay una ventana de solapamiento —24 horas por defecto— durante la cual cada entrega viaja firmada con los dos secretos, el nuevo y el anterior:

X-Met-Signature: t=<ts>,v1=<con el nuevo>,v1=<con el anterior>

Así verifica tu servidor si ya guardaste el secreto nuevo, y también si todavía no. Actualiza tu SDK: las versiones que prueban una sola firma no sirven durante la ventana.

curl -X POST https://api.met.meteor.com.co/api/v1/webhook-endpoints/<id>/rotate-secret \
  -H "Authorization: Bearer $MET_API_KEY"

Si el secreto se te filtró, pide una ventana de 0: el anterior deja de valer de inmediato.

Apagado con aviso. Un endpoint que agota todas sus entregas tres veces seguidas, y lleva al menos 24 horas fallando, se apaga solo y te llega un aviso por correo diciendo por qué. Son las dos condiciones a la vez: una caída de una noche no apaga nada, y un fallo viejo aislado tampoco.

v2.47.0 Nuevo

Nueve eventos más, y una consola para verlos

El catálogo de eventos salientes pasa de 17 a 26. Casi todos ya ocurrían dentro del producto y no salían:

EventoCuándo dispara
automation.run.failedUna automatización falló al ejecutarse.
contact.message.sentSalió un mensaje hacia un contacto, lo haya escrito el Met o una persona.
contact.deletedSe borró un contacto.
broadcast.completedUna difusión terminó de enviarse.
call.missedUna llamada quedó sin contestar.
billing.energy.lowEl saldo de Energía cruzó hacia abajo el umbral bajo.
billing.energy.depletedEl saldo de Energía se agotó.
billing.energy.rechargedEntró una recarga de Energía.
billing.subscription.deactivatedLa suscripción del workspace quedó desactivada.

Los de Energía disparan en el cruce del umbral, no mientras el saldo esté bajo: si no, una cuenta con poco saldo te mandaría un evento por cada ejecución.

Si estás suscrito con el comodín * los vas a empezar a recibir sin hacer nada. Si prefieres enterarte antes de recibirlos, suscríbete a la lista explícita.

Y ahora los puedes ver. En el panel, Desarrolladores → Actividad → Eventos lista lo que genera tu cuenta —lo escuche alguien o no— con su contenido completo y su id, que es el mismo que viaja en la entrega firmada. Sirve para decidir a qué suscribirte antes de escribir una línea de código.

Una precisión sobre el modo de prueba

Un evento se marca como de prueba solo cuando lo disparó una clave de prueba. Lo que no nace de una clave —un mensaje de WhatsApp que entra, un contacto creado desde el panel, un cobro— se queda siempre en vivo, porque no hay un entorno que propagar. Antes esto no estaba dicho en ningún lado; ahora sí, y ya no hay emisores que hereden el valor por descuido.

v2.47.0 Corrección

Corregido: el cuerpo que recibe tu Función son los argumentos, sin sobre

Si registraste una Función IA de tipo HTTP siguiendo nuestra guía, es muy probable que tu handler esté roto. Lo sentimos: el error era nuestro y estaba publicado.

Qué prometíamos. La guía y el SDK decían que tu endpoint recibe un sobre con tres campos, y el ejemplo mostraba call.arguments:

res.json({ result: buscarPrecio(call.arguments) });   // ❌ nunca funcionó

Qué manda Meteor en realidad, y siempre mandó. El cuerpo son los argumentos, planos. Si tu Función declara un parámetro sku, lo que llega es:

{"sku":"A-1"}

No hay sobre, ni id, ni tool, ni un campo arguments que los envuelva. Así que call.arguments era undefined en cada llamada.

Qué cambiamos. Nada del cable: el formato que viaja sigue siendo exactamente el mismo, porque cambiarlo rompería a todas las Funciones que ya están vivas. Lo que corregimos es lo que estaba mal, que era la promesa: el tipo del SDK y la guía. Ahora el handler te devuelve los argumentos directamente:

const handle = met.tools.createHandler(process.env.FIRMA_PRECIOS);
app.post('/precios', (req, res) => {
  let args;
  try { args = handle(req.rawBody, req.headers['x-met-signature']); }
  catch { return res.status(400).end(); }
  res.json({ result: buscarPrecio(args.sku) });   // ✅
});

Qué tienes que hacer. Si tu código lee call.arguments, léelo directo del objeto que te devuelve createHandler. El tipo MetToolCall queda como nombre viejo de MetToolArguments y tu editor te lo va a marcar como obsoleto.

Un GET no lleva cuerpo: ahí los argumentos van en la URL.

v2.47.0 Nuevo

Cuatro lecturas que ya estaban pidiendo, ahora públicas

Miramos qué endpoints estaban intentando llamar con clave de API y recibiendo un rechazo. Cuatro de esos intentos eran razonables y ya no fallan.

GET /workspaces/{id}/channels (channels:read) — la lista de tus canales con su identificador. Cerraba un hueco incómodo: siete operaciones públicas de envío por WhatsApp piden un channelId, y no había forma pública de averiguarlo. Se enviaba a ciegas, o no se enviaba.

GET /channels/{id}/templates (channels:read) — las plantillas aprobadas de un canal de WhatsApp. send-template ya era pública y exige el nombre y el idioma exactos de una plantilla aprobada por Meta; ahora puedes listarlos. Se le piden a Meta en el momento, así que una plantilla recién aprobada aparece de inmediato.

GET /contacts/extraction-catalog (contacts:read) — qué campos puede extraer el análisis de conversaciones de tu cuenta y si está encendido. Sin esto, POST /contacts/{id}/extract devolvía claves que no había cómo interpretar.

GET /billing/automation-usage (billing:read) — tu consumo de automatizaciones contra el techo de tu plan.

Además, la lista de canales ya no incluye la clave de conexión del canal. No la usaba ninguna pantalla y no tenía por qué estar viajando.

v2.46.0 Cambio

Lo que el modo de prueba hace, y lo que nunca hizo

Si leíste nuestra documentación y entendiste que una key met_test_ te daba un entorno aparte, la documentación tuvo la culpa. No lo da, y nunca lo dio. La API no cambió; lo que cambió hoy es lo que decimos de ella.

Lo que una key de prueba sí hace, y sigue haciendo igual:

  • Los runs no debitan Energía y quedan marcados con livemode: false.
  • Hay un tope diario de runs de prueba por workspace. Al alcanzarlo, 429 con test_run_daily_cap — un código que hasta hoy no estaba en ninguna guía y ahora vive en Límites y cuotas.
  • Los siete scopes con efecto externo responden 403 test_mode_restricted: enviar por WhatsApp, ejecutar integraciones, reportar conversiones, provisionar y recargar cuentas, tocar el medio de pago de un partner e instalar plantillas. Vale igual por REST y por el servidor MCP, donde esas herramientas ni siquiera aparecen en el catálogo.

Y lo que no hace, dicho sin rodeos:

  • Corre contra la misma base y las mismas tablas que producción. No hay copia, ni espejo, ni reversión.
  • Escribe de verdad. Lo que está bloqueado es el efecto externo, no la escritura: una key de prueba con items:write o contacts:write crea registros que tu equipo ve en el panel, y nada los borra cuando la key vence.
  • No se puede recoger después. Solo los runs y los eventos llevan la marca livemode; lo demás que escribas queda indistinguible de tu producción, así que no hay forma de pedir "bórrame lo de prueba".

Qué hacer en su lugar: emite la key de prueba con scopes de lectura únicamente (más runs:execute si vas a ejecutar Mets) — lo que no tiene scope de escritura no escribe. Si necesitas escribir, hazlo en un workspace aparte creado para desarrollo, que puedes borrar entero.

Eventos: revisa esto si escuchas con una key de prueba

El filtro por livemode no cruza los dos mundos, pero hoy casi nada se emite como evento de prueba: solo run.completed y run.failed de un run que disparaste con esa key, billing.threshold de la key misma, y el ping de una entrega de prueba. Todo lo demás del catálogo —contact.*, task.completed, conversation.handoff, channel.run.*, app.*, snapshot.*, conversion.*— se emite siempre en vivo, así que una key met_test_ no lo recibe nunca, ni por stream() ni desde el registro.

Si montaste un handler contra esos tipos y lo probaste con una key met_test_, lo que viste no fue un handler que funciona: fue un stream vacío. Pruébalo con una key met_live_.

La clave de demostración del portal sí está aislada

La que te damos en la portada sin pedirte registro es otra cosa, y es lo que buscabas: de solo lectura, con los permisos fijados por el servidor y no por la petición, contra un negocio ficticio cuyo Met solo tiene herramientas de consulta, con su propio tope de Energía y 24 horas de vida. Para mirar la forma real de las respuestas antes de escribir nada, empieza por ahí.