{
  "openapi": "3.1.0",
  "info": {
    "title": "Vida de aquí · Engine",
    "version": "0.1.0",
    "description": "Motor de programación de entrenamiento para Torremolinos y su zona. La IA conversa y convierte lo que la persona cuenta en un intake tipado; Vida de aquí decide la semana con reglas profesionales y explica por qué. Todo lo que devuelve es un BORRADOR en revisión profesional y así debe presentarse. No diagnostica ni trata. No recibe datos personales.",
    "x-versiones": {
      "engine": "0.1.0",
      "ruleset": "2026.08.25-motor-v2",
      "programas": "2026.08.25-blueprints-2",
      "catalogo": "2026.08.24-patrones-1"
    },
    "x-revisado": false,
    "x-aviso": "revisado: false — borrador en revisión profesional; presentar como orientación, nunca como prescripción."
  },
  "servers": [
    {
      "url": "https://vidadeaqui.es/api/ext/v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "clave": {
        "type": "http",
        "scheme": "bearer",
        "description": "Clave de integración vda_… (alternativa: cabecera X-Vida-Key)."
      }
    },
    "schemas": {
      "Intake": {
        "type": "object",
        "description": "Perfil tipado de la persona. Vocabulario CERRADO: un valor fuera de lista se rechaza. Nunca incluyas datos personales ni clínicos.",
        "required": [
          "objetivo",
          "dias",
          "duracion",
          "entorno"
        ],
        "properties": {
          "objetivo": {
            "type": "string",
            "enum": [
              "general_health",
              "strength",
              "hypertrophy",
              "fat_loss_support"
            ],
            "description": "salud general · fuerza · hipertrofia · apoyo a pérdida de grasa"
          },
          "experiencia": {
            "type": "string",
            "enum": [
              "cero",
              "algo",
              "regular"
            ],
            "description": "Base de entrenamiento. Si se pasan historial y parada, mandan ellos."
          },
          "historial": {
            "type": "string",
            "enum": [
              "nada",
              "menos_3",
              "3_6",
              "6_12",
              "mas_12"
            ],
            "description": "Meses seguidos entrenando en el último año."
          },
          "parada": {
            "type": "string",
            "enum": [
              "entreno_ahora",
              "menos_3",
              "3_12",
              "mas_12"
            ],
            "description": "Cuánto lleva parado, si tiene base."
          },
          "dias": {
            "type": "integer",
            "minimum": 1,
            "maximum": 7,
            "description": "Días DISPONIBLES a la semana (no los que se prescriben: eso lo decide el motor)."
          },
          "diasSemana": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "L",
                "M",
                "X",
                "J",
                "V",
                "S",
                "D"
              ]
            },
            "description": "Días concretos disponibles. Si se pasa, manda sobre `dias`."
          },
          "duracion": {
            "type": "integer",
            "enum": [
              30,
              45,
              60,
              75
            ],
            "description": "Minutos por sesión."
          },
          "entorno": {
            "type": "string",
            "enum": [
              "gimnasio",
              "casa_basico"
            ]
          },
          "equipoDisponible": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "maquina",
                "mancuernas",
                "barra",
                "banco",
                "peso_corporal",
                "banda",
                "ninguno"
              ]
            },
            "description": "Material real que tiene. Si no se pasa, decide el entorno."
          },
          "confianzaTecnica": {
            "type": "string",
            "enum": [
              "maquinas",
              "libres",
              "mixto",
              "no_lo_se"
            ],
            "description": "Con qué se maneja. Limita la complejidad técnica de los ejercicios."
          },
          "barrera": {
            "type": "string",
            "enum": [
              "tiempo",
              "mantener",
              "no_se",
              "aburro",
              "comodo",
              "ninguna"
            ],
            "description": "Lo que más le cuesta: cambia el programa, no solo el texto."
          },
          "otraActividad": {
            "type": "object",
            "description": "Actividad que YA hace (pádel, correr, clases…): el motor coloca la fuerza alrededor.",
            "properties": {
              "tipo": {
                "type": "string",
                "enum": [
                  "running",
                  "deporte",
                  "clases",
                  "otro"
                ]
              },
              "dias": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "L",
                    "M",
                    "X",
                    "J",
                    "V",
                    "S",
                    "D"
                  ]
                }
              }
            },
            "required": [
              "tipo",
              "dias"
            ]
          },
          "adaptacion_clinica": {
            "type": "boolean",
            "description": "Si la persona declara dolor, lesión o situación médica que condicione el ejercicio, ponlo a true: el motor NO generará semana y devolverá la ruta a valoración profesional. Nunca describas el problema aquí."
          }
        },
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "codigo": {
            "type": "string",
            "enum": [
              "UNAUTHORIZED",
              "FORBIDDEN",
              "INVALID_INPUT",
              "RULE_CONFLICT",
              "REQUIRES_CONFIRMATION",
              "NOT_SUPPORTED",
              "RATE_LIMITED",
              "RESOURCE_NOT_FOUND",
              "ENGINE_ERROR"
            ]
          },
          "mensaje": {
            "type": "string"
          },
          "detalles": {
            "type": "object"
          }
        }
      }
    }
  },
  "security": [
    {
      "clave": []
    }
  ],
  "paths": {
    "/tools/ver_semana": {
      "post": {
        "operationId": "verSemana",
        "summary": "Genera la semana para un intake y la devuelve resumida (días, frecuencia, estructura, sesiones con sus bloques).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entrada"
                ],
                "properties": {
                  "entrada": {
                    "type": "object",
                    "required": [
                      "intake"
                    ],
                    "properties": {
                      "intake": {
                        "$ref": "#/components/schemas/Intake"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "resultado": {
                      "type": "object"
                    },
                    "request_id": {
                      "type": "string"
                    },
                    "versiones": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Sin clave válida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "La integración no tiene ese scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflicto con una regla (p. ej. esclusa clínica)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas llamadas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tools/explicar_decision": {
      "post": {
        "operationId": "explicarDecision",
        "summary": "Devuelve las decisiones del motor con su regla, versión y estado de revisión, y lo que NO hace y por qué.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entrada"
                ],
                "properties": {
                  "entrada": {
                    "type": "object",
                    "required": [
                      "intake"
                    ],
                    "properties": {
                      "intake": {
                        "$ref": "#/components/schemas/Intake"
                      },
                      "eje": {
                        "type": "string",
                        "description": "Opcional: un eje concreto (frecuencia, arquitectura, complejidad…)."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "resultado": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Sin clave válida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "La integración no tiene ese scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflicto con una regla (p. ej. esclusa clínica)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas llamadas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tools/cambiar_disponibilidad": {
      "post": {
        "operationId": "cambiarDisponibilidad",
        "summary": "«Esta semana no puedo el lunes»: recoloca la semana en los días nuevos y devuelve antes/después, razones y si el cambio requiere confirmación de la persona.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entrada"
                ],
                "properties": {
                  "entrada": {
                    "type": "object",
                    "required": [
                      "intake",
                      "diasSemana"
                    ],
                    "properties": {
                      "intake": {
                        "$ref": "#/components/schemas/Intake"
                      },
                      "diasSemana": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 7,
                        "items": {
                          "type": "string",
                          "enum": [
                            "L",
                            "M",
                            "X",
                            "J",
                            "V",
                            "S",
                            "D"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "resultado": {
                      "type": "object",
                      "properties": {
                        "propuesta": {
                          "type": "object"
                        },
                        "intake": {
                          "type": "object"
                        },
                        "enlace": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Sin clave válida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "La integración no tiene ese scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflicto con una regla (p. ej. esclusa clínica)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas llamadas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/planes": {
      "post": {
        "operationId": "crearPlan",
        "summary": "Guarda un plan y devuelve su enlace en vidadeaqui.es para entregárselo a la persona. Requiere scope program:create. Sin datos personales.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            },
            "description": "Misma clave = mismo plan; evita duplicados por reintentos."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "intake"
                ],
                "properties": {
                  "intake": {
                    "$ref": "#/components/schemas/Intake"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "token": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "resumen": {
                      "type": "object"
                    },
                    "revisado": {
                      "const": false
                    },
                    "repetida": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Sin clave válida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "La integración no tiene ese scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflicto con una regla (p. ej. esclusa clínica)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas llamadas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": false
                    },
                    "codigo": {
                      "type": "string",
                      "enum": [
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "INVALID_INPUT",
                        "RULE_CONFLICT",
                        "REQUIRES_CONFIRMATION",
                        "NOT_SUPPORTED",
                        "RATE_LIMITED",
                        "RESOURCE_NOT_FOUND",
                        "ENGINE_ERROR"
                      ]
                    },
                    "mensaje": {
                      "type": "string"
                    },
                    "detalles": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}