Saltar a contenido

Versionado y deprecación

/v1 es el contrato público de la API de HodeiShield y está congelado: lo que se publica bajo /v1 no cambia de forma incompatible. Esta página resume la política tal como la publica el propio documento OpenAPI (GET /v1/openapi.json), que prevalece si hay discrepancia.

Cómo se identifica la versión

  • La ruta lleva la versión mayor: /v1/….
  • info.version del documento OpenAPI es la revisión del contrato, con forma de fecha. La actual es 2026-10-29. Sube cuando el contrato publicado gana una adición o una corrección.
  • La sección Contract changes del documento OpenAPI lista cada adición y corrección, la más reciente primero, con la revisión en la que llegó. Para saber si una capacidad está presente, comprueba si existe la operación (por ejemplo, GET /v1 lista listPortfolioTenants cuando el contrato de cartera está disponible), no compares cadenas de versión.

Cambios recientes del contrato

  • 2026-10-29, adición: un aviso cuando el valor de un filtro no es uno publicado. severity en GET /v1/alerts, domain y status en GET /v1/risks y status en GET /v1/compliance/controls comparan por igualdad exacta, así que un valor mal escrito (severity=critcal) devolvía una lista vacía que parecía «sin resultados». La petición se sigue atendiendo tal cual, con 200 y los mismos elementos: ningún parámetro acepta menos que antes. Si el valor no está en los x-hs-known-values del parámetro, la respuesta añade además la clave opcional meta.warnings[] (param, value, known) y la cabecera X-HS-Unknown-Filter, que nombra el parámetro. Sin valores desconocidos, ninguna de las dos aparece. category de GET /v1/vendors es texto libre y no se comprueba.
  • 2026-10-27, corrección: un ámbito necesita su módulo activo. Una clave de API de inquilino o una clave de cartera se atendía sólo por su ámbito, aunque el inquilino ya no tuviera activo el módulo de ese ámbito. Ahora toda credencial recibe 403 con error.details.code MODULE_NOT_ENTITLED en ese caso, y un ámbito compliance.<marco> exige además que el marco esté activado en el inquilino. Una petición que antes respondía 200 ahora responde 403. La misma revisión añade GET /v1/changes (ámbito changes:read, sólo lectura).
  • 2026-10-26, cambio: user.email exige el ámbito email. GET /v1/me devuelve user.email sólo a un token de acceso OAuth que lleve el nuevo ámbito email, y lo omite en caso contrario; la llamada nunca se rechaza por no tenerlo. Trata user.email como opcional.

Cambios compatibles (ocurren dentro de /v1, sin aviso previo)

  • una operación nueva;
  • un parámetro de consulta nuevo y opcional;
  • un campo nuevo en un objeto de respuesta;
  • un valor nuevo en un campo documentado como vocabulario abierto (por ejemplo status, severity, evidence_type);
  • un error.code nuevo, siempre con el estado HTTP que ya usan sus hermanos;
  • cualquier cosa bajo error.details, que es diagnóstico y no forma parte del contrato, salvo error.details.code y las claves que la tabla de errores de cada operación nombra.

Escribe tu cliente para que esto no lo rompa: ignora los campos desconocidos, no hagas un switch exhaustivo sobre un vocabulario abierto y trata un error.code desconocido como «un error de este estado HTTP».

Cambios incompatibles (no ocurren en /v1)

Van a una versión nueva (/v2), y /v1 sigue sirviéndose:

  • quitar o renombrar una operación, un parámetro o un campo;
  • cambiar el tipo, la unidad o el significado de un campo;
  • hacer obligatorio un parámetro opcional, o aceptar menos de lo que aceptaba;
  • cambiar el ámbito que exige una operación;
  • cambiar el estado HTTP con el que se envía un error.code existente.

Valores desconocidos en un filtro

Un filtro con vocabulario publicado (x-hs-known-values) no rechaza un valor desconocido: la petición responde 200 con lo que coincide, que casi siempre es nada. Para que eso no se confunda con «no hay resultados», la respuesta lleva meta.warnings[] con un elemento { "param", "value", "known" } por cada filtro desconocido, y la cabecera X-HS-Unknown-Filter con los nombres de los parámetros separados por comas. Se aplica a severity de las alertas, domain y status de los riesgos y status de los controles de cumplimiento; los valores en español en retirada de severity no generan aviso. La cabecera obsoleta Warning no se usa.

Valores en retirada

Un valor que se retira de un parámetro se lista en el documento OpenAPI con la extensión x-hs-deprecated-values, y la fecha hasta la que el servidor documenta que lo acepta, en x-hs-deprecated-values-sunset. Hoy hay un caso: los valores en español del filtro severity de las alertas (critico, alto, medio, bajo) se documentan como aceptados hasta el 2027-01-14; cambia a los valores en inglés (critical, high, medium, low, info) antes de esa fecha.

Lo que no forma parte del contrato congelado

  • Los límites de uso pueden subir sin aviso. Ver Límites de uso.
  • Las cabeceras de firma de los webhooks tienen su propio ciclo: la firma heredada X-HodeiShield-Signature se retirará. Ver Webhooks.

Lo que esta política no establece

El contrato no fija cuánto tiempo seguirá sirviéndose /v1 cuando exista /v2, ni un plazo de aviso para retirarlo. No tomes esta página como un compromiso sobre ello.