09Versionado y cambios

Sección 09

Versionado y cambios

.md

Versión de este contrato

ContratoRevisión del protocoloEstado
v1MCP 2026-07-28 recomendada · revisiones anteriores admitidasVigente

El contrato se ancla a 2026-07-28, pero eso no obliga a su servidor a hablarla: un servidor de la revisión anterior se certifica igual y se registra con su era. El detalle está abajo, en Las dos eras del protocolo.

Política de cambios

  • Cambio compatible (herramienta nueva, campo opcional nuevo, código de error nuevo): se publica y entra en vigor de inmediato. No requiere acción de su parte.
  • Cambio incompatible (campo obligatorio nuevo, límite más estricto, código de error retirado): se anuncia con 90 días de antelación y las dos versiones conviven durante ese periodo.
  • Cambio de revisión del protocolo: se adopta con un periodo de convivencia anunciado. La propia especificación incorpora desde 2026-07-28 una política formal de obsolescencia. Un servidor ya certificado no deja de funcionar por un cambio de versión del estándar.

Cuatro cambios incompatibles para que la primera llamada salga

Entran juntos y sin los 90 días de convivencia de la política de arriba, con el acuerdo de la única cuenta integrada, que no tenía ninguna llamada completada ni ningún consumo. Se declaran igual porque cambian supuestos razonables de quien integra.

1 · En pruebas, solo números verificados, y hasta 5

Una clave ak_test_ solo llama a un número de prueba verificado de su cuenta; hasta 5 por cuenta, contando pendientes y verificados. La transferencia de la conducta de pruebas también va solo a uno verificado.

Qué tiene que hacer. Registre y verifique sus números en la consola, en Números de prueba (página 14). Llamar a otro responde 409 test_destination_not_verified.

2 · En producción, número propio obligatorio

Una clave ak_live_ ya no sale con un número de Asixto cuando su cuenta no tiene el suyo. Sin número propio listo, la llamada no sale y no se cobra: 409 phone_number_required, 409 phone_number_in_review o 402 phone_number_suspended.

Qué tiene que hacer. Tenga su número y su expediente aprobados antes de pasar a live. Qué significa cada código, en la página 14.

3 · El excedente exige un medio de pago verificado

Con el consumo por excedente encendido, si su cuenta no tiene un medio de pago verificado, el excedente no cuenta: cuando el saldo no cubre la operación, recibe 402 insufficient_credits, como si estuviera apagado.

Qué tiene que hacer. Agregue un medio de pago en la consola, o recargue créditos.

4 · El entorno de pruebas ya no tiene techo de créditos propio

Lo que estas páginas publicaban como baranda —que un bucle de pruebas se cortaba contra el cupo de su entorno antes de vaciar el presupuesto de producción— se retira. Una cuenta de la beta nace sin techo de créditos por periodo en ningún entorno, y pruebas y producción gastan del mismo saldo.

Qué tiene que hacer. Fije un tope de gasto de la cuenta que le sirva también para sus pruebas (página 16).

Tres cambios incompatibles ya en vigor

Van juntos porque los tres afectan a código o a presupuesto que quizá ya tiene decidido, y cada uno trae lo que le toca hacer. Los tres estaban en vigor antes de este aviso, así que no tuvieron el periodo de convivencia de la política de arriba. Se declara en vez de disimularse: es lo que le permite explicar un 403 que no esperaba o un consumo que creía gratis.

1 · El entorno de pruebas cobra, y al mismo precio

Una clave ak_test_ ejecuta de verdad y consume créditos a los mismos precios que una ak_live_ (página 12). No hay tarifa de pruebas ni descuento: el cobro no es un eje que distinga entornos. Lo que separa test de live es la concurrencia propia de cada entorno, a quién puede llamar y el aislamiento de sus datos, no el proveedor ni el precio.

Es una decisión con consecuencia, y por eso se publica en vez de dejarla en la letra pequeña: la alternativa —devolverle una respuesta simulada— haría que certificar no significara nada, porque estaría certificando contra un resultado que su cliente final nunca va a recibir.

Qué tiene que hacer. Cuente sus pruebas en su presupuesto, no como tráfico gratis. Lo que acota su gasto es el tope de gasto de la cuenta (página 16): el entorno de pruebas ya no tiene un techo de créditos propio (cambio 4 de la sección anterior).

2 · La identidad con la que sale la llamada, y telephony_not_ready retirado

El error telephony_not_ready se retiró y no vuelve: en live sin número propio listo lo que llega ahora es uno de los tres códigos del cambio 2 de la sección anterior. Retirar un código del catálogo es, por la política de arriba, un cambio incompatible, y así se clasifica aquí. La descripción del cambio está en la entrada del 2026-09-08 del historial.

Lo que faltaba decir es el segundo eje, y es el que cambia lo que oye quien reciba la llamada:

EntornoCon qué número sale
liveEl suyo, obligatorio: desde el cambio 2 de la sección anterior ya no sale uno de Asixto de reserva (página 14)
testSiempre uno de Asixto: en pruebas el número del tenant no se mira, aunque lo tenga (página 14)

Qué tiene que hacer. Si su código trataba telephony_not_ready como el caso «todavía no puedo llamar», retire esa rama: ya no llega. Y no dé por hecho en pruebas el número que verá en producción — si lo que valida es el identificador de origen, valídelo con una clave ak_live_.

3 · Leer el stream del turno lo autoriza jobs:read

Abrir el turno y leer su stream son dos permisos distintos: agent:converse origina el trabajo, jobs:read lee su respuesta (página 19). Una clave sin jobs:read paga el turno y recibe 403 insufficient_scope al abrir el stream (página 16).

Dos consecuencias, y las dos son contrato:

  • Toda clave nace con las lecturas que no gastan nada: jobs:read y agents:read, se pidan o no, porque sin ellas quien ya integró no puede leer lo que pagó ni encontrar el agente al que llamar. agent:converse no se concede así: es irreversible y es la capacidad más cara de la superficie, y no se regala a una clave que se emitió para transcribir audio.
  • No existe ningún agent:read para leer un turno, y no se va a crear: eso lo autoriza jobs:read. Leer la LISTA de sus agentes es otro recurso y tiene su propio permiso, agents:read (página 15). El vocabulario de scopes es cerrado: un nombre que no esté en él se rechaza al emitir, no al usar.

Qué tiene que hacer. Mire los scopes de las claves que ya tenía emitidas: si a alguna le falta jobs:read, esa clave no puede leer sus propios trabajos ni sus streams, y si le falta agents:read —porque se emitió antes de que ese permiso existiera— recibirá 403 insufficient_scope al listar sus agentes. El camino es el mismo en los dos casos: emitir una clave nueva desde la aplicación y rotarla en su despliegue. Ampliar una clave viva concede exactamente lo que se pida, así que un permiso nuevo no aparece solo en las que ya tiene.

Compatible y ya en vigor: contexto por petición en las dos operaciones con agente

POST /v1/calls y POST /v1/agent/turns aceptan dos objetos opcionales nuevos, variables y metadata (página 15). Es un cambio compatible: sin ellos, las dos operaciones se comportan exactamente igual que antes.

Lo que sí conviene que sepa aunque no los use:

  • Las respuestas correctas pueden traer ahora una clave warnings de primer nivel. Es opcional y ausente cuando no hay nada que avisar, así que un receptor que ignore claves desconocidas no necesita cambios.
  • Los eventos job.* pueden traer metadata dentro de data (página 11) — solo si usted lo mandó en la petición.
  • Si su agente tiene huecos {{clave}} en su saludo o su mensaje de apertura y usted no manda variables, la petición se rechaza con 400 validation_error nombrando la clave que falta. Un agente sin huecos no se ve afectado: es la configuración la que los introduce, y la hace usted en la consola.
  • Repetir una Idempotency-Key con otras variables responde 409 idempotency_key_reused. El reintento de la misma petición sigue siendo idempotente.

Qué cambió en la revisión 2026-07-28 del protocolo

Relevante si su equipo conoce revisiones anteriores o encuentra ejemplos antiguos:

CambioEfecto en su servidor
Protocolo sin estadoDesaparecen el saludo de inicialización y el identificador de sesión. Cada petición es autónoma; puede desplegar en serverless o edge.
Nuevo server/discoverSu servidor debe implementarlo para anunciar versiones, capacidades e identidad.
Fuera la reanudación de flujoUna respuesta cortada se reintenta como petición nueva. Por eso la idempotencia es obligatoria.
resultType en todo resultadoEl Gateway solo consume resultados completos. Si su servidor es de una revisión anterior y no emite el campo, se trata como complete (SEP-2322): no hay que hacer nada.
subscriptions/listenSustituye la suscripción anterior para avisar cambios de catálogo. Opcional.
Cabeceras Mcp-Method y Mcp-NameRequeridas en cada POST. Las pone el SDK.
Orden determinista en tools/listRecomendado por la especificación para preservar la caché del modelo.
Registro dinámico de cliente obsoletoSustituido por documentos de metadatos de cliente. No lo requiera.

Los SDK oficiales de TypeScript, Python, Go y C# implementan esta revisión en su línea v2.

Las dos eras del protocolo, y las dos se admiten

La especificación distingue dos formas de acordar qué se habla, y Asixto acepta las dos:

EraCómo se reconoceEstado
modernserver/discover anuncia supportedVersions con 2026-07-28. La versión y las capacidades del cliente viajan en el _meta de cada petición; no hay estado de sesión.Recomendada
legacyResponde al saludo initialize con una revisión que soporta (2025-11-25 o anterior).Admitida

Lo que no se admite es ninguna de las dos: sin supportedVersions y sin respuesta a initialize no hay forma de acordar la revisión, y eso sí bloquea.

La era NO se declara: la detectamos al dar de alta el servidor. Al registrarlo hablamos con su entorno de pruebas, leemos cómo acuerda la revisión y la guardamos; a partir de ahí el Gateway le habla en la que corresponda y no la deduce en caliente. La consecuencia práctica es una precondición: su entorno de pruebas tiene que estar desplegado y respondiendo en el momento del alta. Si no acordamos revisión con él, el alta se rechaza diciéndole qué anunció y qué falta.

Cuidado con el caso intermedio. Un servidor puede responder server/discover con el cuerpo de initialize —un protocolVersion en singular y la identidad en la raíz—. Eso es un servidor legacy, aunque el nombre del método sugiera lo contrario, y así lo clasifica el verificador: mira el contenido de la respuesta, no que el método exista. Si su documentación anuncia 2026-07-28, conviene que el servidor lo cumpla o que la documentación diga la revisión real.

Referencias

Historial de este documento

FechaVersiónCambio
2026-08-14v1.0Publicación inicial. Contrato anclado a MCP 2026-07-28.
2026-08-26v1.0Compatible. Se admiten las dos eras del protocolo: un servidor de revisión anterior (initialize) se certifica igual y la era se declara al darlo de alta. Se aclara que la ausencia de resultType se trata como complete. Y la página 08 publica el comando del verificador de conformidad. Ninguna de las tres cosas exige cambios en un servidor ya construido.
2026-08-18v1.0Compatible. El _meta de tools/call suma com.asixto/locale (idioma de atención del tenant, BCP 47): los textos legibles van en ese idioma (página 02). No exige cambios en su servidor: si lo ignora, siga devolviendo español neutro.
2026-08-28v1.0Compatible. Nace la página 13: retención con cifra por tipo de dato —la entrada no se persiste, el resultado vive 24 h, la ventana de la sesión 24 h de inactividad—, la lista de los proveedores que reciben contenido suyo, el borrado a petición y qué no se cobra. La página 10 deja de decir «la ventana acordada para su cuenta», que no era un dato verificable. Corrección de facturación en el mismo cambio: una respuesta que el sistema marca como no entregada ya no se cobra, y una cantidad que no se puede medir se cobra al mínimo de la operación y no al máximo autorizado.
2026-08-29v1.0Compatible. Se publica la referencia de la API (etapa 2): página 14 primeros pasos y entornos, página 15 las siete operaciones campo por campo con ejemplos ejecutables, página 16 el catálogo completo de errores con qué hacer en cada caso, y página 17 trabajos, retención del resultado y los cinco casos de una clave de idempotencia repetida. Solo HTTP: no hay SDK. Nada de esto cambia el contrato de un servidor de herramientas ya construido; lo que hace es publicar lo que la API ya hacía y que solo se podía averiguar preguntando.
2026-09-08v1.0Compatible. Tres cambios que sí se notan. (1) El veredicto de una certificación admite un tercer valor, inconclusive: una corrida que no pudo OBSERVAR ninguna comprobación bloqueante ya no se rinde como aprobada. Si su código enruta el webhook certification.finished con un if aprobada / else fallida, ahora puede recibir un tercero, y significa «no lo pudimos comprobar», no «su servidor falló». (2) Se retira el error telephony_not_ready: ya no hace falta aprovisionar nada para llamar. Si su cuenta no tiene número propio, la llamada sale con un número de Asixto; cuando le asignemos uno suyo, sale con ese sin que cambie la petición (página 15). El catálogo de errores pasa de 30 códigos a 29. (3) La página 13 declara el tipo de proveedor que recibe cada contenido en vez de su nombre; la lista nominal se entrega bajo acuerdo al contacto técnico que la pida. (4) El informe de certificación distingue cuatro resultados por comprobación en vez de tres: se separa «no pudimos medirla» de «todavía no automatizada», que son las que revisamos con su equipo y no cambian por repetir la corrida. La página 08 dice fila por fila cuál es cuál, y un aviso ya no se presenta como un fallo. (5) Publicar el catálogo es un acto propio, distinto de certificar: hasta que lo ordena, un servidor registrado y aprobado no aporta ninguna herramienta al agente. Es la fase 3 de la página 08 y se hace desde la aplicación. Ninguno de los cinco exige cambios en un servidor ya construido.
2026-09-09v1.0Incompatible. Se declaran juntos los tres cambios que ya estaban en vigor y que rompen un supuesto razonable de quien ya integró. (1) El entorno de pruebas cobra, y al mismo precio: ak_test_ ejecuta de verdad y consume créditos como ak_live_. (2) La llamada de ak_test_ sale siempre con un número de Asixto —en pruebas el número propio del tenant no se mira—, y el error telephony_not_ready queda retirado: retirar un código del catálogo es, por la política de esta página, un cambio incompatible, así que se reclasifica lo anunciado el 2026-09-08. (3) Leer el stream del turno lo autoriza jobs:read, no el scope con el que se abrió, así que una clave emitida antes de este cambio puede pagar un turno y no poder leerlo; toda clave nueva nace con ese scope y no existe ningún agent:read. Qué hacer en cada caso: Tres cambios incompatibles ya en vigor.
2026-09-09v1.0Compatible. La página 11 publica la forma de data campo por campo para los once eventos del catálogo, que era la mitad del sobre que faltaba: ya puede tipar y probar su receptor sin esperar a recibir una entrega. Con dos avisos que rompen un receptor descuidado: job.expired no trae result, y los tres eventos de saldo son el único caso en el que una clave puede faltar en vez de llegar en null.
2026-09-10v1.0Compatible. La era de protocolo se comprueba al dar de alta el servidor, no solo al certificar: leemos el catálogo de su entorno de pruebas y, si anuncia otra revisión que la declarada, el registro se rechaza en el momento indicándole la que observamos. Solo se rechaza cuando la desalineación se observa: si su entorno de pruebas todavía no responde, o la lectura falla por otro motivo, el alta se completa igual y la era se comprueba al certificar. No exige cambios en un servidor ya construido, y un servidor ya registrado no se toca: lo que evita es gastar una corrida de certificación en un dato que ya se podía cotejar (fase 1 de la página 08).
2026-09-11v1.0Compatible. Su agente admite un segundo tipo de regla, que se configura en la aplicación y no cambia nada de su servidor. Las que ya tenía son deterministas: un disparador cerrado —palabra clave, emoción, intentos— ejecuta una herramienta sin que el modelo decida. Las nuevas son por instrucción: usted redacta la condición con sus palabras y el agente decide cuándo aplica; si les asocia una herramienta, se le ordena ejecutarla al cumplirse, y solo puede ser una de su catálogo certificado. No son deterministas: son una instrucción con prioridad alta, no un if. Y puede crear sus propias carpetas para agruparlas: varias reglas en la misma carpeta, en orden, describen un flujo por pasos. Eliminar una carpeta no borra sus reglas.
2026-09-11v1.0Compatible. Se publica el análisis de video, POST /v1/video/analysis, que la API ya atendía y solo se podía averiguar preguntando: se manda la URL del video que usted aloja, lo autoriza el permiso video:analyze y se factura con el código video_analysis. La tarifa es plana, 270 créditos por video, así que uno de diez segundos y uno de cinco minutos cuestan lo mismo (página 12); por eso su entrada tiene dos techos —50 MiB y 600 segundos— y pasarlos rechaza la petición nombrando el techo en vez de analizar parte del video. Campos, límites y ejemplos ejecutables en la página 15. No exige cambios en una integración ya construida: una clave emitida sin video:analyze sigue funcionando igual para todo lo demás, y para llamar a esta operación emita otra que lo lleve.
2026-09-11v1.0Compatible. La página 13 publica cuánto vive cada dato, con cifra y separado por propósito, que era la mitad que faltaba de la retención: la entrada no se persiste, el resultado y la ventana de conversación viven 24 h, el registro de uso 400 días y el asiento contable el plazo legal. Los 400 días son fijos para todas las cuentas y cubren un año cerrado más el margen para reclamar el último periodo; dentro de la ventana puede consultar el detalle petición a petición, y Asixto se reserva servir solo el resumen de los tramos más antiguos. Si necesita historia más larga, expórtela: el resumen de uso y los webhooks son continuos. La misma página publica ahora las cifras de la baja de la cuenta —la pide el Propietario, hay 30 días de gracia en los que se cancela, y al ejecutarse se borra todo lo del Gateway salvo los registros de facturación, que la ley obliga a conservar anonimizados— y declara que la grabación de la llamada no existe: Asixto no almacena el audio de una llamada de /v1/calls.
2026-09-11v1.0Incompatible. El tope de gasto del excedente pasa a tener un techo del proveedor: el efectivo es el menor entre el que usted fija y el que Asixto financia, y dejarlo sin fijar ya no significa «ilimitado» —resuelve al techo—. El techo empieza en 20 USD y sube con el historial de pago (3 ciclos pagados a tiempo ⇒ 100 USD; 6 ⇒ 500 USD, que es el máximo absoluto), nunca con el consumo. Una factura vencida o devuelta lo devuelve al primer escalón. Qué cambia en la práctica: una operación puede responder 402 spending_cap_reached donde antes no lo hacía, y el aviso credits.spending_cap_reached se levanta una vez por periodo. Medido antes de publicarlo: cero cuentas afectadas hoy —ninguna tiene el excedente encendido—, y se declara igual porque cambia un supuesto razonable de quien ya integró. Recargar saldo no levanta un tope: eso sigue igual (página 12).
2026-09-21v1.0Incompatible. Dos comprobaciones nuevas en la certificación y una severidad corregida, las tres sobre la descripción y la forma de sus herramientas. (1) readOnlyHint era ya obligatorio para publicar —una herramienta sin él no entra en el catálogo, porque no podemos saber si escribe— pero el verificador público solo lo avisaba: leía «0 bloqueantes» y perdía la herramienta al publicar. Ahora es bloqueante en los dos sitios, y la página 02 deja de decir que su ausencia se resuelve por omisión. (2) Nace «Descripciones sin inyección», bloqueante: una descripción que intenta gobernar al modelo («ignora las instrucciones anteriores», system prompt, pedirle que no use otras herramientas, marcas de rol) o que trae caracteres invisibles ya no pasa. Su descripción llega a nuestro modelo en el mismo contexto que las instrucciones de la empresa, así que esto no es estilo; lo que sí es estilo —«llama siempre a esta herramienta»— sigue siendo aviso. (3) «Una operación por herramienta» pasa a refutarse sola en el caso concluyente: un parámetro cuyo enum deja elegir entre un método HTTP de lectura y uno que escribe. Publique una herramienta de lectura y una por cada acción que escribe. Y una tercera fila, solo aviso: le decimos si su URL de pruebas está en otro dominio que su producción, con los dos hosts, para que compruebe que apunta a su servidor MCP y no a otro servicio suyo. Todo lo demás del contrato queda igual (página 08).
2026-09-16v1.0Incompatible. La era de protocolo deja de pedirse: la detectamos nosotros. El campo desaparece del alta —si su cliente llama a la API de la consola con él, quítelo— y en su lugar el registro adquiere una precondición: su entorno de pruebas tiene que estar desplegado y respondiendo en el momento de dar de alta, porque hablamos con él para leer cómo acuerda la revisión. Antes se declaraba y se cotejaba con lo observado; eso le hacía adivinar un dato técnico que nosotros ya leemos del cable, y dejaba pasar el alta con la era declarada y sin comprobar cuando su servidor no respondía —un estado que nadie sabía interpretar—. Ahora hay tres desenlaces y los tres se dicen con nombre: la detectamos y su servidor queda registrado con la era ya comprobada; no acordamos revisión con su entorno de pruebas y el alta se rechaza diciéndole qué anunció y qué desplegar; o falla nuestro lado, y entonces lo decimos con esas palabras y basta reintentar en unos minutos. Un servidor ya registrado no se toca. Sigue siendo cierto que las dos eras se admiten y que migrar es opcional (fase 1 de la página 08).
2026-10-09v1.0Incompatible. Cuatro cambios para que la primera llamada de una integración salga, aplicados sin periodo de convivencia con el acuerdo de la única cuenta integrada. (1) Con ak_test_ solo se llama a un número de prueba verificado de la cuenta, hasta 5 por cuenta entre pendientes y verificados; si no, 409 test_destination_not_verified. (2) Con ak_live_ el número propio es obligatorio: sin él listo, 409 phone_number_required, 409 phone_number_in_review o 402 phone_number_suspended, y ya no sale un número de Asixto de reserva. (3) El excedente exige un medio de pago verificado; sin él, el saldo que no alcanza responde 402 insufficient_credits. (4) Se retira la baranda que publicaban las páginas 09, 16 y 18: el entorno de pruebas ya no tiene techo de créditos propio. Qué hacer en cada caso: Cuatro cambios incompatibles.
2026-10-09v1.0Compatible. (1) El cupo con el que nace una cuenta sube a 10 peticiones y 5 llamadas simultáneas por entorno, sin techo de créditos por periodo (página 18). (2) Si a una cuenta se le fija un techo y la operación no cabe ni con el periodo vacío, responde 409 request_exceeds_period_quota, sin Retry-After. (3) El acuse de POST /v1/calls puede traer warnings.transfer_disabled cuando la transferencia de pruebas sale apagada, y el replay de una Idempotency-Key devuelve los mismos warnings que el acuse original (página 15). (4) Los rechazos por destino de prueba o por número propio no abren trabajo: no se cobran y no consumen la clave. (5) La bienvenida de 3.000 créditos se acredita sola, una vez por cuenta, cuando tiene el módulo y un medio de pago verificado (página 12). (6) La fase 4 de la certificación pasa a ser el Playground y las llamadas a sus números de prueba (página 08).