Changelog · página 8 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 30 jul 2026 – 2 ago 2026. También puedes suscribirte al feed.

v2.23.0

El destinatario de WhatsApp ya no siempre es un teléfono

Qué cambió

WhatsApp está habilitando los usernames: una persona puede elegir un nombre de usuario y conversar contigo sin darte su número. Cuando eso pasa, Meta deja de enviar el teléfono y en su lugar manda un identificador propio, el *business-scoped user ID* (CO.13491208655302741918), que es específico de tu cuenta: el mismo cliente tiene otro identificador distinto en otro negocio.

Por eso el dry-run de plantillas —POST /channels/{channelId}/whatsapp/send-template con dry_run=true— tiene un campo nuevo:

{
  "dry_run": true,
  "would_send": {
    "recipient": "CO.13491208655302741918",
    "phone_number_id": "109876543210987",
    "template": { "name": "recordatorio_cita", "language": "es" }
  }
}

would_send.to sigue siendo el teléfono y llega igual que siempre para los contactos que lo tienen. Cuando el contacto llegó por username, to no viene y en su lugar está recipient. Siempre recibes uno de los dos, nunca los dos a la vez.

Qué tienes que hacer

Si lees would_send.to para mostrarlo o registrarlo, deja de asumir que existe:

const destino = would_send.to ?? would_send.recipient;

Nada más cambia. Los envíos reales siguen funcionando igual y no tienes que pasar el identificador a mano en ninguna llamada: Met resuelve solo a quién le habla, según lo que Meta nos haya dado de ese contacto.

Por qué te conviene mirarlo ahora

Si guardas a tus clientes usando el teléfono como llave, esa llave va a faltar para quien adopte un username — y ahí no vas a poder reconocerlo ni volver a contactarlo. Conviene que tu sistema empiece a guardar también el identificador y que no exija el número para crear un registro.

v2.24.0

Los conteos de bandeja responden por lo que estás mirando

GET /contacts/counts ahora acepta filtros

Hasta hoy el endpoint devolvía siempre los totales del workspace. Si querías saber cuántos chats abiertos tiene una asesora, el conteo no te servía: había que traer la lista y contarla en tu código.

Ahora acepta los mismos parámetros que GET /contacts — q, status, assigned_to, agent_group, channel_id, tag, unread, autopilot y filters — y devuelve los conteos facetados.

Facetado quiere decir que cada bloque se calcula con todos los filtros activos menos el suyo:

GET /contacts/counts?assigned_to=42&status=open
  • Los cinco contadores de estado (open, pending, human_requested, finished, archived) cuentan los chats de la asesora 42, ignorando status.
  • Los de asignación (total, mine, unassigned, byUser) cuentan los chats abiertos, ignorando assigned_to.
  • byGroup ignora agent_group; byChannel ignora channel_id.

Un bloque que se aplicara su propio filtro daría cero en todas las demás opciones, y quien lo lee se quedaría sin forma de saber qué hay del otro lado.

Un campo nuevo: scopeTotal

{ "total": 287, "scopeTotal": 164, "open": 5, "...": "..." }

scopeTotal es el universo de la carpeta que elegiste — el asesor, el grupo o el canal — sin estado, búsqueda ni filtro avanzado. Es el denominador honesto de un "viendo N de M": total cambia con cada filtro que agregas, así que no sirve para decir de cuánto estás viendo una parte.

Qué no cambia

Si llamas al endpoint sin parámetros, la respuesta es la de siempre: los totales del workspace. scopeTotal es un campo nuevo que se agrega, no reemplaza a ninguno, y los conteos siguen respetando la visibilidad de quien consulta.

El contrato y la referencia ya están actualizados.

v2.23.0

El pipeline de oportunidades tiene una etapa nueva, Negociación

NEGOCIACION, entre Propuesta y Ganado

El campo stage de una oportunidad acepta un valor más: NEGOCIACION. Va justo después de PROPUESTA y antes de GANADO.

curl -X POST https://api.partners.meteor.com.co/leads \
  -H "Authorization: Bearer $MET_API_KEY" \
  -d '{"company_name":"Acme","stage":"NEGOCIACION"}'

El embudo completo queda así: NUEVO → CONTACTADO → CALIFICADO → PROPUESTA → NEGOCIACION → GANADO, con PERDIDO al costado y ACTIVADO al final, que sigue siendo terminal y la escribe Meteor al vincular la oportunidad con su cuenta.

Antes, todo lo que pasaba entre mandar la cotización y firmar vivía en PROPUESTA. Con las dos cosas en la misma etapa, el conteo no distinguía la oportunidad que espera trabajo tuyo de la que espera la firma del cliente.

Qué hacer con tu integración

Es un valor nuevo, no un cambio de los que ya usabas: nada de lo que hoy envías deja de funcionar, y ninguna oportunidad cambió de etapa sola. Si tu código tipa stage como una lista cerrada de valores, regenera tu cliente o suma NEGOCIACION a mano antes de leer oportunidades que ya estén ahí.

npm install @meteor.ia/sdk@latest
v2.22.0

La referencia ahora dice qué es cada grupo y lleva a su guía

Cada operación tiene un enlace a la guía que la explica

Hasta hoy el viaje era de ida: las guías enlazaban a la referencia, y la referencia no devolvía a ninguna parte. Si llegabas a POST /items buscando cómo se usa de verdad, no tenías desde dónde saltar.

Ahora las 300 operaciones y los 36 grupos del contrato llevan externalDocs con el enlace a su guía. No es un cambio del portal: está en openapi.public.json, así que también lo ve tu cliente generado y cualquier herramienta que lea el contrato.

Además, los grupos dejaron de ser encabezados mudos. El documento declaraba tags: [] — la referencia mostraba Slugs, Item Content o handoff sin una línea que dijera qué son. Ahora cada uno trae su descripción, y los tres cuyo nombre técnico no se lee bien tienen nombre visible (agent-groups → Grupos de Mets).

El contrato dice contra qué versión estás generando

info.version estaba clavado en 1.0.0 desde el primer día. Ahora lleva la versión del changelog, así que el número que ves en el contrato es el mismo que encabeza la entrada donde se explica qué cambió.

curl -s https://developers.meteor.com.co/public/openapi.public.json | jq .info.version

Guárdalo el día que generes tu cliente: comparar contra el changelog te dice exactamente qué pasó en el medio.

Versionado y deprecación, escritos

Nueva guía: Versionado y deprecación. Dice qué cambios puedes esperar sin aviso (y cómo escribir tu integración para que no te rompan), cuáles nunca ocurren sin un ciclo previo, y qué pasa exactamente cuando un endpoint se va a retirar.

Lo concreto: mientras un endpoint deprecado siga vivo responde normal, pero cada respuesta trae Deprecation: true, un Sunset con la fecha de retiro y un Link con la alternativa. Si registras los headers de tus llamadas salientes, esa es la forma más barata de no enterarte tarde. Hoy no hay ningún endpoint deprecado.

v2.21.0

El contrato dejó de listar schemas que ninguna operación usa

144 schemas de menos, ninguna operación de menos

El contrato público declaraba 504 schemas, pero solo 360 estaban referenciados por alguna de las 300 operaciones. Los otros 144 eran tipos que ninguna ruta pública usa: llegaban al documento porque estaban definidos en el mismo servidor, no porque formaran parte de la API.

Ahora el contrato solo incluye lo que alguna operación alcanza.

Si generas un cliente desde el contrato, esto se nota. Un generador emite una clase, un tipo o un modelo por cada schema del documento — con lo que hasta ayer tu SDK generado traía 144 tipos que no podías usar para nada, porque ningún endpoint los recibe ni los devuelve. Ese ruido desaparece.

Todo lo demás queda igual y se verificó explícitamente: las 300 operaciones siguen ahí, con su schema de respuesta y con los cuatro errores comunes (400, 401, 429, 500) que se documentaron en la 2.19.0.

Qué no cambia

Ningún endpoint, ninguna ruta, ningún campo de ninguna respuesta. Si ya generaste tu cliente y no usabas esos tipos —no podías—, regenerarlo no te va a romper nada.

El contrato y la referencia ya están actualizados.

v2.20.0

La referencia ya dice qué devuelve cada endpoint

298 de 300 operaciones con su respuesta documentada

Hasta hoy la referencia te decía qué falla, qué acepta y qué es obligatorio, pero no qué contesta. Para saber la forma de una respuesta había que llamar al endpoint y mirar el JSON.

Ahora cada operación declara su schema de salida: los campos, sus tipos y cuáles pueden venir en null. Se ve en el "Try it" de la referencia y, sobre todo, lo usan los generadores de clientes — si generas tipos desde el contrato, ahora salen completos en vez de unknown.

Las dos que no lo declaran es porque no devuelven JSON: GET /events/stream es un stream text/event-stream y GET /item-files/{fileId}/download son los bytes del archivo. Las dos dicen eso mismo en la referencia.

Los schemas abiertos siguen siendo abiertos, y ahora se nota. Un contacto, un ítem o una fila de colección llevan los campos personalizados de tu workspace, así que su schema declara los campos garantizados y marca explícitamente que pueden venir más. Antes esa distinción no estaba escrita en ninguna parte y un cliente generado podía descartar tus campos propios sin avisar.

Los POST documentan 201, que es lo que responden

Si creas algo con un POST —una tarea, un contacto, un ítem, un webhook— la API responde 201 Created. La referencia decía 200 en varias de esas operaciones.

Si tu integración valida el código de estado, revisa que aceptes 201 y no solo 200. El comportamiento del API no cambió: siempre respondió 201; lo que se corrigió es lo que decía la documentación.

Dos precisiones que evitan un error común

  • Los mensajes de un contacto piden conversations:read, no contacts:read. Una key con permisos de contactos lista contactos pero no lee sus conversaciones. La guía de contactos decía lo contrario.
  • Un recordatorio le llega al contacto, como plantilla de WhatsApp aprobada. No existe el modo "nota interna": el campo message es el texto que va a leer el contacto y note es el único que no se envía. Está dicho ahora en la referencia de POST /reminders.
v2.19.0

Un agente ya puede agendar un seguimiento y buscar archivos; el CLI suma plantillas y tickets

MCP: 34 herramientas

Agendar un seguimiento. Cuando un agente no puede resolver algo ahora, tenía una sola salida: pasarle el turno a un humano. Ahora tiene la otra — quedar en escribirle al contacto después.

met_create_reminder agenda el mensaje, met_list_reminders muestra los pendientes, met_update_reminder mueve la fecha y met_cancel_reminder lo detiene.

Un recordatorio le llega al contacto por WhatsApp a la hora agendada, como plantilla aprobada; no es una nota interna. El workspace necesita tener configurada su plantilla de recordatorio (Ajustes). Detalle completo en Operación del workspace.

Encontrar un archivo. met_list_assets busca en la mediateca del workspace por nombre o por tipo, y devuelve el enlace. Es lo que hace falta cuando el agente tiene que enviar el catálogo, la lista de precios o una ficha: encuentra el archivo y pasa el enlace en el mensaje.

Subir archivos no se hace por MCP —eso es POST /workspaces/{id}/assets, que recibe multipart— porque pasar un archivo por una herramienta significaría mandar sus bytes codificados en el mensaje del modelo.

CLI 0.5.0

met snapshots install 3f1e… --set negocio="Muebles del Norte"
met partner tickets reply 84 "Ya quedó corregido, prueba de nuevo"

met snapshots monta una plantilla completa en el workspace desde un script o desde CI, que es lo que necesitas al dar de alta un cliente nuevo. list y show <slug> recorren el catálogo —show imprime las variables que pide, con * en las obligatorias—, claim da acceso a las gratuitas e install la instala.

La instalación es aditiva e idempotente y todo llega desactivado. install imprime el id de la instalación en stdout, así que en un pipeline lo guardas y revisas antes de prender nada.

Aquí --set no convierte tipos: un teléfono o un NIT quedan como texto. Si una variable de verdad no es texto, pásala en JSON con --vars '{"cupo":10}'.

met partner tickets es la primera escritura del grupo partner, y la única que va en una terminal: responder soporte se hace de a uno y suele ser urgente. list muestra tus tickets, show <id> imprime el hilo completo y reply <id> "mensaje" responde. Abrir y cerrar un ticket siguen siendo del panel.

npm i -g @meteor.ia/cli
v2.18.0

Si eres partner, ya puedes conectar tu agente a tu cartera por MCP

Tu key de partner ahora abre un servidor MCP con 13 herramientas sobre tu propio negocio: clientes atribuidos, comisiones, liquidaciones, oportunidades, proyectos y tickets.

https://api.partners.meteor.com.co/mcp

Es un endpoint distinto del de Met, y con qué key te autenticas decide cuál usar: una key de workspace habla con el MCP de Met (api.met.meteor.com.co/api/v1/mcp), y una key de partner con este. Los dos objetos —un workspace y una cartera de clientes— no comparten permisos, así que tampoco comparten catálogo.

Tu key necesita el scope mcp:use para abrir la sesión, y cada herramienta pide además su partner:*. Una herramienta cuyo scope no tienes no aparece en el catálogo.

Qué trae

dominioherramientas
Clienteslist_clients
Finanzaslist_commissions, list_payouts
Oportunidadeslist_leads, get_lead, create_lead, list_lead_comments, comment_lead
Proyectoslist_projects, list_project_tasks
Soportelist_tickets, get_ticket, reply_ticket

Todas con el prefijo met_partner_.

Lo que queda fuera, y por qué

Mover una oportunidad de etapa y borrarla están en la API REST y no en el MCP. Cambiar la etapa de un negocio o eliminarlo se decide mirando el tablero, con el contexto de la conversación con el cliente delante — no es algo que convenga delegar a un modelo en medio de un intercambio. Lo mismo con cerrar o reabrir un ticket: puedes responderlo por MCP, el estado se cambia desde el panel.

Y una nota que vale para cualquier herramienta: el partner sobre el que operas sale de tu key, no de un argumento. No hay forma de pedirle a una herramienta que lea la cartera de otro partner.

Ejemplo con Claude Desktop

{
  "mcpServers": {
    "meteor-partners": {
      "type": "http",
      "url": "https://api.partners.meteor.com.co/mcp",
      "headers": { "Authorization": "Bearer met_live_tu_key_de_partner" }
    }
  }
}

Detalle de los scopes y del modelo de keys en Partners API.

v2.17.0

El MCP ya lee conversaciones y pasa el turno a un humano; el CLI suma Mets, consumo y webhooks

MCP: 26 herramientas

Leer la conversación. met_get_messages devuelve los mensajes del hilo con un contacto, del más viejo al más nuevo. Es la contraparte de met_send_message: con las dos, un asistente puede responder sabiendo qué ya se dijo.

Pasarle el turno a un humano. met_set_autopilot prende o apaga la atención automática de un contacto, y met_pause_autopilot la suspende por N minutos y la reanuda sola.

Para una intervención puntual usa met_pause_autopilot. Apagar el autopiloto es permanente hasta que alguien lo prenda, y es fácil que un contacto quede sin atención automática durante semanas. Con minutos, se reanuda solo; con 0, reanuda ya.

Elegir qué Met ejecutar. met_list_agents lista los Mets del workspace con su nombre, que es lo que después pasas como hint a met_run_agent.

Los dominios de configuración —webhooks, automatizaciones, funciones, integraciones— no tienen herramientas MCP a propósito: se configuran una vez desde el panel y no son algo que un agente resuelva en medio de una conversación.

CLI 0.4.0

met agents list              # los Mets del workspace
met billing ejecuciones      # el detalle de consumo, ordenado por costo
met webhooks events 12       # historial de entregas, con el código HTTP

met agents te da el nombre que necesitas para met run --met <nombre>. Y met agents show <id> imprime sus herramientas, que es lo que suele explicar por qué un Met no hace algo: casi siempre le falta la herramienta, no el prompt.

met billing tiene tres vistas. resumen es el agregado del período, ejecuciones el detalle ordenado por costo —donde se ve qué está gastando de verdad— y saldo el estado de la cuenta. saldo avisa además si la recarga automática está apagada: en una integración desatendida, quedarse sin Energía detiene las tareas.

met webhooks complementa met listen. Ese trae los eventos a tu máquina; esto muestra qué intentó entregar Meteor y con qué respondió tu servidor. Si events sale vacío, el webhook no se ha disparado — revisa el disparador antes que tu endpoint. met webhooks sample <id> dispara un evento de prueba.

Es solo lectura y prueba: crear un webhook o rotar su secreto se hace desde el panel, para que el secreto no quede en tu historial de shell.

npm i -g @meteor.ia/cli
v2.16.1

Los tres endpoints de flujos ya declaran qué error devuelven

Nada cambió en el comportamiento del servidor. Esto es la referencia poniéndose al día con lo que la API ya hacía.

Las tres operaciones de importación y exportación de flujos —FlowsController_importFlow, FlowsController_importPreview y FlowsController_exportFlow— ya declaran sus respuestas de error en el spec: 400, 401, 429 y 500, apuntando a los mismos componentes de error que el resto de la API. Antes las devolvían igual y el spec no lo decía, así que un cliente generado desde la referencia no tenía tipo para el caso de falla y quedaba adivinando la forma del cuerpo.

Si usas el SDK, actualízalo y los tipos llegan solos. Si construiste tu cliente desde el spec, vale regenerarlo: son las tres operaciones que más se llaman desde scripts, y 429 en un importador que corre en lote es un caso que conviene manejar.

Y cuatro schemas que salen de components, sin efecto para nadie: CreateDashboardDto, CreateWidgetDto, DemoGreetingDto y QuerySpecDto estaban declarados sin una sola propiedad y sin ninguna operación que los usara. Eran artefactos de generación, no contratos — el mismo caso que WhatsappWabaTargetDto la semana pasada. Si alguno aparece en tu cliente generado, es un tipo vacío que nada devuelve.

El conteo de operaciones no se movió: 300 antes y 300 ahora, ninguna agregada y ninguna retirada.

v2.16.0

La referencia ya muestra qué devuelve cada endpoint, e iteradores para paginar por desplazamiento

Qué devuelve cada endpoint

Los cinco dominios más usados —runs, tareas, contactos, ítems y colecciones— ya declaran la forma de su respuesta en el contrato. Como los campos llevan ejemplos, la referencia te muestra la respuesta sin que necesites una key.

Si generas clientes a partir del OpenAPI, hay una diferencia entre ellos que conviene tener presente:

  • Runs tiene schema cerrado: la lista de campos está completa.
  • Tareas, contactos, ítems y colecciones tienen schema abierto (additionalProperties: true). Esos endpoints devuelven la fila completa, y los campos dependen del esquema de tu workspace y de tus campos personalizados. Se documentan los campos garantizados y se declara explícitamente que puede venir más — así tu cliente generado no descarta lo que no está en la lista.

Paginar por desplazamiento

Si paginas facturación, Mediateca, eventos, entregas de webhook o la búsqueda de ítems, revisa tu código.

Esos endpoints paginan con limit + offset (la búsqueda de ítems, con limit + page). Mandarles starting_after no da error: el parámetro se ignora, la respuesta es 200, y recibes la primera página una y otra vez.

En el SDK, billing.executions() y billing.transactions() ahora reciben offset en vez de starting_after. Si paginabas con starting_after, cámbialo.

Y hay iteradores para no escribir el bucle a mano:

for await (const e of met.billing.iterateExecutions()) { /* ... */ }
for await (const a of met.assets.iterate({ mime_prefix: 'image/' })) { /* ... */ }
for await (const it of met.items.iterateSearch('factura')) { /* ... */ }
for e in met.billing.iterate_executions():
    ...
for a in met.assets.iterate(mime_prefix="image/"):
    ...

Una advertencia del terreno: el desplazamiento no es estable. Si algo entra o sale del conjunto mientras recorres, una fila puede aparecer dos veces o ninguna. Para un barrido exacto sobre datos que se mueven, usa los endpoints con cursor —runs, contactos, ítems de una colección— y su iterate().

Las dos formas de paginar, con cuál te toca en cada dominio, están en Errores, idempotencia y paginación.

v2.15.0

WhatsApp interactivo, difusiones, carpetas y una guía nueva de operación

WhatsApp más allá del texto, en CRM y contactos. Botones (hasta 3), listas, respuestas citadas, reacciones, ubicación y ficha de contacto. El id de cada botón es tuyo y es lo que te vuelve cuando la persona elige, así que ponle algo que puedas interpretar sin una tabla aparte.

Lo que conviene saber antes de escribir código: fuera de la ventana de 24 horas desde el último mensaje de la persona, WhatsApp solo permite escribir con plantillas aprobadas por Meta. Es un límite de Meta y no se puede saltear.

Difusiones, en la misma guía. Dos cosas que cambian cómo las usas: previewCount resuelve el segmento y te dice a cuánta gente le va a llegar sin enviar nada, y una difusión no manda un mensaje suelto sino que arranca un flujo por cada contacto del segmento — por eso puede responder, ramificar y encadenar pasos.

Carpetas y slugs, en Datos: colecciones e ítems. El slug de un ítem es único dentro de su colección, no de todo el workspace. Y una distinción que ahorra dolores de cabeza: el código lo genera Meteor y no cambia; el slug lo pones tú y puede cambiar, así que no lo uses como identificador estable en tu base.

Guía nueva: Operación del workspace — consumo de Energía, archivos, conversaciones, recordatorios, autopiloto y grupos de agentes. Son cinco dominios que se consultan juntos cuando ya estás en producción. Lo que trae:

  • Cuando el consumo no cuadra, la respuesta está en billing.executions(), no en el agregado. Y si tu integración es desatendida, revisa autoRecharge(): quedarse sin Energía detiene las tareas.
  • Un recordatorio hace dos cosas distintas. Con channel_id y template_name se envía al contacto a la hora agendada; sin ellos es una nota interna para el equipo.
  • Para intervenir una conversación puntualmente, pauseAutopilot — no setAutopilot(false). Apagarlo es permanente hasta que alguien lo prenda; pausado con minutos se reanuda solo.
  • Los grupos de agentes son de personas, no de Mets. addMember recibe un user_id. Para acotar un Met, lo que se usa son sus habilidades y herramientas.
  • assets.cleanupProvisional() corre en simulación por defecto. Mira el resultado antes de pasar true; no es reversible.

Con esto el portal va en 20 guías, y la primera es Cómo construir un agente de IA.