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

v1.4.0

Línea de tiempo del contacto, tareas vinculadas y extracción de datos con IA

Tres cosas nuevas en el dominio de contactos, todas aditivas:

  • GET /contacts/{id}/timeline (contacts:read, met.contacts.timeline()): la historia del contacto en una sola lista — cambios de campo, eventos de sistema (estado, asignación), notas internas y tareas de seguimiento. Cada entrada trae un type discriminador (field_change, system_event, note, task, contact_created), así que no hay que inferir nada de la forma del dato. No incluye los mensajes de la conversación: para eso está messages(). Cursor: before = created_at de la última entrada recibida.
  • Tareas vinculadas al contacto: POST /workspaces/{ws}/tasks acepta contact_id, y GET /workspaces/{ws}/tasks?contact_id= devuelve las de un contacto. La respuesta sigue siendo un array plano — no cambiamos la forma de un endpoint ya publicado. Las tareas traen responsable, fecha límite, pasos y comentarios del módulo de Tareas: no hay entidad nueva.
  • POST /contacts/{id}/extract (contacts:write): completa con IA los campos vacíos del contacto con lo que se dijo en la conversación. Dos cosas importantes: consume energía (aparece en tu ledger como crm_extraction) y es fill-only — nunca pisa un dato existente. Está apagada por defecto: si el workspace no la habilitó en Ajustes, el endpoint devuelve filled: [] sin llamar al modelo ni cobrarte.

También, si construiste automatizaciones: se retiró del catálogo el disparador contact.status_changed. Estaba deshabilitado y ningún evento lo emitía nunca — no se podía usar, así que no hay nada que migrar. Para reaccionar a un cambio de estado o de etapa, usa contact.field_updated con el campo correspondiente ($status o etapa), que funciona hoy.

v1.3.0

Embudo comercial en contactos, totales agregados y catálogo de campos personalizados

El CRM estrena pipeline. La decisión de diseño importa para quien integra: no hay una entidad "oportunidad" nueva. El embudo son campos personalizados del contacto, así que se leen y escriben con las tools de contactos que ya usas, y todo lo que construiste encima sigue funcionando igual.

  • Tres campos sembrados en cada workspace: etapa (lista: Nuevo, Calificado, Propuesta, Negociación, Ganado, Perdido), monto (moneda) y fecha_cierre_estimada (fecha). Se siembran solo si no existían: si tu workspace ya tenía un campo con ese field_key, se respeta el tuyo — ni sus opciones ni su etiqueta se tocan. Mover una etapa es un PATCH /contacts/{id} normal, y dispara los mismos disparadores de contact.field_updated de siempre.
  • GET /contacts/pipeline-summary (scope contacts:read, met.contacts.pipelineSummary()): conteo y suma por etapa, agregados en la base sobre todos tus contactos, no sobre una página. Los contactos sin etapa se agrupan en __no_value__. Acepta stage_field/amount_field si tu workspace usa otros nombres.
  • met.variables (scopes variables:read/variables:write): los endpoints de campos personalizados ya eran públicos pero el SDK no los exponía. met.variables.fieldDefinitions() es la única forma de descubrir qué campos tiene un workspace y qué valores acepta cada lista — imprescindible para escribir en ellos sin adivinar.
  • Tipo de campo currency: nuevo tipo para las definiciones de campos de contacto. El código ISO de la moneda va en options (['COP']) y el valor del contacto es solo el número, para que sume limpio.
  • Documentada la convención de claves, que era invisible y es la causa más común de errores al escribir: los campos de sistema llevan $ ($name, $status); los personalizados, su field_key pelado (etapa, monto). Mandar $etapa no falla — guarda una clave que ninguna vista lee, y el dato queda invisible. Está en la guía de contactos.
v1.2.0

Paginado por cursor en contactos (arregla el barrido completo) y vistas de tareas en el contrato

Si barrías tu lista de contactos con contacts.iterate() del SDK, solo recibías la primera página y el barrido terminaba declarando éxito. Este release lo arregla y deja el recurso alineado con el paginado por cursor del resto de la API (§3.9):

  • GET /contacts devuelve has_more. El campo faltaba, así que el auto-paginado del SDK lo leía como undefined y cortaba en la página 1. total y page siguen intactos: si ya consumes la respuesta actual, nada cambia para ti.
  • Cursor estable con starting_after. GET /contacts?order=id&starting_after=<id del último contacto> pagina por cursor sobre un orden inmutable. El orden por defecto (recencia de la conversación) se reordena con cada mensaje entrante: un barrido sobre él se saltea contactos que saltan a la primera página a mitad del recorrido. Por eso el cursor exige order=id, y hay que pedirlo desde la primera página.
  • contacts.iterate() ya lo hace solo. El SDK pide order=id y encadena el cursor por ti; actualiza a la última versión y el barrido recorre todos tus contactos. Si paginabas a mano con page, sigue haciéndolo — pero para exports completos prefiere el cursor.

También, sin cambios de código: el contrato publicado estaba desactualizado y ya incluye las vistas de tareas (/workspaces/{ws}/task-views, /task-views/{viewId}, …/task-views/reorder, con scopes tasks:read / tasks:write). Están vivas desde el 15 de julio; lo que faltaba era su documentación en el spec.

v1.1.0

Autoría de flujos por API key, filtros de items, PATCH parcial y adjuntar por URL

Un paquete de mejoras nacido de integrar cotizadores y pipelines comerciales contra la API pública. Reduce fricción en automatización-como-código y en la gestión de datos no-code:

  • Autoría de flujos y automatizaciones con la key de servicio. Las mutaciones de flujos (POST/PATCH/DELETE/duplicar en /workspaces/{ws}/flows[/{id}]) y de disparadores (POST/PATCH/DELETE en /workspaces/{ws}/automations) ya no exigen el JWT de sesión: se emiten con los scopes nuevos flows:write y automations:write. Permite versionar la automatización como código y editarla desde CI.
  • Filtro y orden de items en el servidor. GET /collections/{id}/items acepta filter[campo]=valor (o filter[campo][op]=valor, con op ∈ eq, neq, gt, gte, lt, lte, like, ilike, in) y sort=-updated_at,campo. Ya no hace falta bajar la colección entera y filtrar en el cliente. Sobre claves de data, las comparaciones son de texto.
  • PATCH parcial de un item. PATCH /collections/{id}/items/{itemId} fusiona (merge) las claves recibidas en data sin reemplazar el objeto completo — evita las carreras del PUT. Complementa el PATCH …/field (un solo campo) existente.
  • Adjuntar un archivo por URL. POST /items/{itemId}/files acepta además un cuerpo JSON { url, filename }: Met descarga el archivo (con protección anti-SSRF) y lo guarda, sin streamear los bytes por multipart. La respuesta ahora incluye download_url (URL firmada de descarga directa).
  • dry_run en envíos de plantilla. POST /channels/{id}/whatsapp/send-template?dry_run=true valida plantilla y parámetros y devuelve el mensaje resuelto sin entregarlo — útil para verificar el payload en desarrollo.
  • Firma HMAC saliente en el nodo _Petición HTTP_. El nodo http.request puede firmar su cuerpo con un secreto del workspace y enviar la firma en X-Met-Signature (HMAC-SHA256), verificable en el destino — reemplaza el pasar una clave en la query.
  • Contrato más rico. Los DTOs de envíos de WhatsApp y de disparadores traen properties y examples; el POST con Idempotency-Key queda documentado en el contrato (reintento seguro sin duplicados).
v1.7.0

Marketplace de Snapshots — catálogo e instalación por API

Ya puedes descubrir e instalar plantillas de implementación (Snapshots) con tu API key. Un Snapshot empaqueta la configuración de un workspace —Mets, flujos, colecciones, habilidades e integraciones, sin secretos ni datos vivos— y se instala en otro workspace de forma aditiva e idempotente.

Nuevos endpoints públicos:

  • GET /workspaces/{workspaceId}/snapshot-catalog y GET /workspaces/{workspaceId}/snapshot-catalog/{slug} — navega el catálogo de plantillas publicadas y consulta la ficha de una (qué incluye, qué deberás conectar, vista previa de la guía). Requiere el scope snapshots:read.
  • POST /workspaces/{workspaceId}/snapshot-catalog/{snapshotId}/claim — reclama el acceso gratuito a una plantilla (crea el *entitlement*). Requiere snapshots:install.
  • POST /workspaces/{workspaceId}/snapshots/{snapshotId}/install — instala la última versión lista en el workspace. Corre como job asíncrono e idempotente por *provenance*: reinstalar no duplica. Requiere snapshots:install.
  • POST /workspaces/{workspaceId}/snapshots/{snapshotId}/submit — envía tu Snapshot a revisión editorial para publicarlo en el marketplace. Requiere snapshots:publish (solo partners).

La instalación es aditiva (nunca borra nada del workspace destino) y todo lo ejecutable llega desactivado hasta que lo enciendas. El pago de plantillas de pago y la distribución por *share link* siguen siendo superficie interna por ahora.

v1.6.0

Webhooks de apps OAuth + rotación de secreto con gracia

Dos mejoras para quienes construyen apps OAuth de terceros:

  • Eventos app.authorized y app.revoked — ahora te avisamos por webhook cuando un workspace autoriza o revoca tu app. El evento se entrega al workspace dueño de la app (el que la registró), no al que autoriza — igual que account.application.authorized de otros ecosistemas. Suscribite desde Desarrolladores → Actividad → Webhooks (requiere el scope integrations:read). El payload trae client_id, el workspace_id que autorizó, los scopes y el grant_id — sin datos personales del usuario.
  • Rotación de secreto con ventana de gracia (24h) — al rotar el client_secret de una app confidencial, el secreto anterior sigue siendo válido durante 24 horas. Así puedes desplegar el nuevo secreto sin una ventana de caída: los dos autentican mientras haces el cambio, y el viejo caduca solo.

Sin cambios en el contrato de la API pública: los access tokens OAuth siguen operando con los mismos scopes, cuota y Energía que una API key.

v1.5.0

OAuth 2.0 para apps de terceros

Ya puedes construir apps que otros workspaces de Meteor autorizan para operar en su nombre, sin pedirles nunca una API key. Es el estándar OAuth 2.0 Authorization Code + PKCE:

  1. Registras tu app en Ajustes → Desarrolladores y obtienes un client_id (y un client_secret si es confidencial).
  2. Rediriges al usuario a la pantalla de consentimiento de Meteor, donde ve tu app y los permisos exactos que pides.
  3. Al aprobar, recibes un código que canjeas en POST /oauth/token por un access token (Bearer, 1h) y un refresh token.
  • PKCE obligatorio (S256) — protege el flujo también para apps públicas (nativas/SPA) que no pueden guardar un secreto.
  • Scopes acotados — tu app declara sus scopes máximos y el usuario aprueba un subconjunto; jamás alcanzas más de lo que la app registró, y nunca scopes de partner.
  • Refresh con rotación — cada refresh emite uno nuevo e invalida el anterior; si un token robado se reusa, la sesión entera se revoca automáticamente.
  • Control del usuario — quien te autorizó ve tus apps en Ajustes → Desarrolladores y puede revocar el acceso cuando quiera (cae en cascada sobre tokens y refresh).

Los access tokens OAuth operan la misma API pública, con los mismos scopes, cuota y Energía que una API key — nada de superficie nueva del lado del recurso.

v1.4.0

Stream de eventos en vivo + met listen

Nuevo endpoint para escuchar los eventos de tu workspace en tiempo real, y el comando de CLI que cierra el dev-loop de webhooks:

# Reenvía cada evento a tu app local, firmado igual que en producción
met listen --forward http://localhost:3000/webhooks
  • GET /events/stream (events:read) — suscripción SSE efímera al flujo de eventos del workspace. No crea un webhook persistente: es para desarrollo e inspección. Cada evento llega como el mismo envelope público que entrega un webhook (event: message).
  • Filtrado seguro — el stream solo emite eventos cuyo scope de lectura porta tu key (una key events:read sin billing:read no ve billing.threshold), y respeta el modo: una key met_test_ solo ve eventos de test. Opcionalmente, ?types=run.completed,run.failed.
  • met listen --forward <url> — reenvía cada evento a tu servidor local con la misma firma HMAC (X-Met-Signature) que en producción, usando un secreto de firma efímero que el CLI imprime al arrancar. Así tu handler local corre exactamente la misma verificación (constructEvent) que usará en vivo — sin túneles ni configuración extra.

Para entrega garantizada y con reintentos en producción, sigue usando los webhooks persistentes; met listen es el compañero de desarrollo.

v1.3.0

SDK oficial de Python (meteor-ia)

Ya puedes construir sobre Meteor desde Python, con la misma ergonomía que el SDK de TypeScript:

from meteor_ia import Met

met = Met(os.environ["MET_API_KEY"], workspace_id=7)
run = met.runs.create("Resume los leads de hoy", met="ventas")

for event, data in met.runs.stream("Hola"):
    print(event, data)
  • Misma superficie curada — runs, agents, contacts, tasks, collections, items, billing, integrations, webhooks y partner.*. Mismos scopes, mismas rutas, mismo contrato que el SDK de TS.
  • Sin dependencias — usa solo la stdlib (urllib, hmac, json). pip install meteor-ia y listo.
  • Producción por defecto — reintenta 429/5xx con backoff (respeta Retry-After), Idempotency-Key automático en los POST, auto-paginación (.iterate()), streaming SSE (for event, data in met.runs.stream(...)) y errores tipados (MetRateLimitError.retry_after, MetAuthError, …).
  • Webhooks seguros — construct_event(payload, signature, secret) verifica la firma HMAC saliente sin pegarle a la red.

Server-side only: tu API key met_* es secreta.

v1.2.0

Presupuestos de Energía por API key + webhook billing.threshold

Ahora puedes ponerle un tope de gasto de Energía mensual a cada API key y enterarte antes de que se agote:

  • Presupuesto por key — en *Ajustes → Desarrolladores* asignas un tope en USD por key (al crearla o después, sin rotarla). El consumo se mide del mismo ledger que cobra — no un contador aparte.
  • Aviso 50 / 80 / 100 % — te llega un email al dueño de la key en cada umbral, una sola vez por mes. Sin sorpresas a fin de mes.
  • Corte automático opcional (hard-stop) — si lo activas, al llegar al 100 % las nuevas solicitudes se rechazan con 429 budget_exceeded hasta el próximo mes o hasta que subas el tope. Si no, la key sigue operando y solo avisa.
  • Nuevo evento saliente billing.threshold — suscribe un webhook (scope billing:read) y recibe el cruce de cada umbral como evento: { api_key_id, level, period_month, budget_usd, spent_usd, currency }. Ideal para dashboards o para pausar tus jobs automáticamente.

Además, el consumo de Energía ahora se mide de forma completa: la generación de imágenes con GPT Image y la búsqueda semántica (RAG) debitan Energía con la misma política de precios que el resto de la plataforma (costo del proveedor + el margen de tu plan).

v1.1.0

Test mode, Developer Workbench, webhooks salientes y helpers del SDK

Esta versión suma las capacidades de las fases F2–F4 del plan:

  • Test mode (met_test_) — las keys de test corren el orquestador real sin costo (los runs de test se debitan a $0), con un cap diario por workspace. Los scopes con efecto externo (integrations:execute, channels:send, workspaces:provision) devuelven 403 test_mode_restricted.
  • Developer Workbench — Registros de requests (con request_id correlacionable vía X-Request-Id, sin bodies), Resumen de consumo (volumen, errores, latencia p95) y Salud (errores por code del catálogo + alertas de cuota). En Met y Partners.
  • Eventos salientes (webhooks firmados) — registras endpoints y Meteor te hace POST cuando pasa algo (run.completed, run.failed, contact.*, task.completed, conversation.handoff), con firma HMAC X-Met-Signature y reintentos con backoff.
  • Helpers del SDK — met.webhooks.constructEvent() verifica la firma de un evento saliente; met.tools.createHandler() hace lo mismo para endpoints HTTP que Meteor invoca como tools.
  • GitHub Secret Scanning — una key met_live_/met_test_ filtrada en un repo público se revoca automáticamente.
v1.1.0

Partners API — proyectos de implementación

met.partner.* suma su segundo dominio de crecimiento:

  • GET /partner/projects — proyectos de implementación donde el partner es originador o implementador, con el scope partner:projects:read. En el SDK: met.partner.projects.list().
  • Read-only y curado — fase, estado, precio (price_amount/price_status), título, descripción, deadline, workspace del cliente y nombres de originador/implementador. Omite los ids internos de partner y la mecánica del tablero.

Sigue en "Próximamente": partner:leads:write y workspaces:provision.