{
  "openapi": "3.0.3",
  "info": {
    "title": "Lera API",
    "version": "v1",
    "description": "API de gestion de Lera. Autenticacion con clave secreta (lera_sk_) en la cabecera Authorization, como Bearer. Documentacion en https://leracore.com/developers"
  },
  "servers": [
    {
      "url": "https://leracore.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "parameters": {
      "LeraClient": {
        "name": "X-Lera-Client",
        "in": "header",
        "required": false,
        "description": "Solo cuentas partner, y solo con la clave de la cuenta raiz. Ejecuta la operacion sobre uno de tus clientes (su workspace_id, que devuelve GET /api/v1/partner/clients) o sobre todos con \"all\". \"all\" solo vale en consultas y devuelve el resultado etiquetado por cliente, en clients en vez de en result.",
        "schema": {
          "type": "string"
        }
      }
    }
  },
  "paths": {
    "/api/v1/tools/get_agent": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Devuelve la configuración completa de un agente por su id: prompt, voz, funciones y límites.",
        "operationId": "get_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_agent_templates": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Devuelve las plantillas de agente disponibles por sector, para partir de una en lugar de una hoja en blanco.",
        "operationId": "list_agent_templates",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_agents": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Devuelve los agentes del workspace con su tipo, modo, estado y plantilla de origen.",
        "operationId": "list_agents",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/create_agent": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Crea un agente de voz en borrador. Con los datos del negocio, el prompt se genera al nivel de las plantillas.",
        "operationId": "create_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nombre del agente, para reconocerlo en el panel.",
                    "example": "texto de ejemplo"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "voice",
                      "chat"
                    ],
                    "description": "Si el agente es de voz o de chat.",
                    "example": "voice"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "single_prompt",
                      "conversation_flow"
                    ],
                    "description": "Cómo se construye el agente: prompt único o flujo por nodos.",
                    "example": "single_prompt"
                  },
                  "template_key": {
                    "type": "string",
                    "description": "Plantilla de sector de la que partir. Las devuelve list_agent_templates.",
                    "example": "texto de ejemplo"
                  },
                  "business_name": {
                    "type": "string",
                    "description": "Nombre real del negocio. Se usa en el saludo y en el prompt.",
                    "example": "texto de ejemplo"
                  },
                  "summary": {
                    "type": "string",
                    "description": "A qué se dedica el negocio, en una frase. Se usa para generar el prompt.",
                    "example": "texto de ejemplo"
                  },
                  "services": {
                    "type": "array",
                    "description": "Servicios del negocio. Alimentan el prompt y lo que el agente sabe ofrecer.",
                    "example": []
                  },
                  "tone": {
                    "type": "string",
                    "description": "Tono con el que habla el agente (cercano, formal, directo…).",
                    "example": "texto de ejemplo"
                  },
                  "transfer": {
                    "type": "boolean",
                    "description": "Si el agente debe poder pasar la llamada a una persona.",
                    "example": true
                  },
                  "prompt": {
                    "type": "string",
                    "description": "Instrucciones del agente: qué hace, qué pregunta y cómo responde.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "texto de ejemplo",
                "kind": "voice",
                "mode": "single_prompt"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/duplicate_agent": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Duplica un agente existente como un borrador nuevo, sin tocar el original.",
        "operationId": "duplicate_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/import_agent": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Crea un agente en este workspace desde un JSON exportado. Hay que volver a poner los secretos a mano.",
        "operationId": "import_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_export": {
                    "type": "object",
                    "description": "El objeto que devolvió export_agent, tal cual.",
                    "example": {}
                  }
                },
                "required": [
                  "agent_export"
                ]
              },
              "example": {
                "agent_export": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/export_agent": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Exporta un agente a un JSON portable para llevarlo a otro workspace. Los secretos salen redactados.",
        "operationId": "export_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/publish_agent": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Publica el borrador y crea una versión activa. Hasta publicar, las llamadas siguen usando la versión anterior.",
        "operationId": "publish_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/set_business_hours": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Define el horario del negocio, su zona horaria y los días especiales. No apaga al agente: le da la información.",
        "operationId": "set_business_hours",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Poner o quitar el horario. Quitarlo no apaga al agente.",
                    "example": true
                  },
                  "time_zone": {
                    "type": "string",
                    "description": "Zona horaria con la que se decide si está abierto.",
                    "example": "texto de ejemplo"
                  },
                  "weekly": {
                    "type": "array",
                    "description": "Los tramos de cada día, de lunes a domingo. Siete listas, ni una más ni una menos.",
                    "example": []
                  },
                  "exceptions": {
                    "type": "array",
                    "description": "Festivos, puentes y vacaciones. Sustituyen al horario semanal en esas fechas.",
                    "example": []
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "enabled": true,
                "time_zone": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/set_call_recording": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Activa o desactiva la grabación del audio. Al activarla, el agente dice un aviso legal fijo que no se puede quitar.",
        "operationId": "set_call_recording",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Enciende o apaga la grabación del audio de las llamadas de este agente.",
                    "example": true
                  },
                  "purpose": {
                    "type": "string",
                    "enum": [
                      "calidad",
                      "contratacion",
                      "incidencias",
                      "formacion"
                    ],
                    "description": "Para qué se graba. Queda registrado junto al consentimiento.",
                    "example": "calidad"
                  },
                  "retention_days": {
                    "type": "object",
                    "description": "Días que se guarda el audio. Solo puede ACORTAR el plazo del workspace.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "enabled"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "enabled": true,
                "purpose": "calidad",
                "retention_days": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/update_agent": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Actualiza el borrador de un agente: nombre, prompt, saludo, voz, modelo, comportamiento y bases de conocimiento.",
        "operationId": "update_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "description": "Nombre del agente, para reconocerlo en el panel.",
                    "example": "texto de ejemplo"
                  },
                  "prompt": {
                    "type": "string",
                    "description": "Instrucciones del agente: qué hace, qué pregunta y cómo responde.",
                    "example": "texto de ejemplo"
                  },
                  "tone": {
                    "type": "string",
                    "description": "Tono con el que habla el agente (cercano, formal, directo…).",
                    "example": "texto de ejemplo"
                  },
                  "agent_name": {
                    "type": "string",
                    "description": "Nombre con el que se presenta el agente al descolgar.",
                    "example": "texto de ejemplo"
                  },
                  "business_name": {
                    "type": "string",
                    "description": "Nombre real del negocio. Se usa en el saludo y en el prompt.",
                    "example": "texto de ejemplo"
                  },
                  "begin_message": {
                    "type": "string",
                    "description": "Frase fija de saludo. Vacía, la improvisa el modelo en cada llamada.",
                    "example": "texto de ejemplo"
                  },
                  "farewell_message": {
                    "type": "string",
                    "description": "Frase fija de despedida. Vacía, la improvisa el modelo.",
                    "example": "texto de ejemplo"
                  },
                  "voice_provider": {
                    "type": "string",
                    "description": "Proveedor de la voz. Determina qué voces se pueden elegir.",
                    "example": "texto de ejemplo"
                  },
                  "voice_id": {
                    "type": "string",
                    "description": "Identificador de la voz en su proveedor. Solo voces del propio workspace.",
                    "example": "cmk1a2b3c..."
                  },
                  "model": {
                    "type": "string",
                    "description": "Modelo de lenguaje del agente. Marca latencia y fiabilidad.",
                    "example": "texto de ejemplo"
                  },
                  "runtime_mode": {
                    "type": "string",
                    "enum": [
                      "cascade",
                      "sts"
                    ],
                    "example": "cascade"
                  },
                  "sts_provider": {
                    "type": "string",
                    "enum": [
                      "openai",
                      "google"
                    ],
                    "example": "openai"
                  },
                  "sts_model": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "greeting_enabled": {
                    "type": "boolean",
                    "description": "Si habla primero el agente o espera a que hable quien llama.",
                    "example": true
                  },
                  "greeting_interruptible": {
                    "type": "boolean",
                    "description": "Si se le puede cortar el saludo.",
                    "example": true
                  },
                  "speak_when_silent": {
                    "type": "boolean",
                    "description": "Ante silencio, comprueba una vez si la persona sigue ahí antes de colgar.",
                    "example": true
                  },
                  "knowledge_base_ids": {
                    "type": "array",
                    "description": "Ids de las bases de conocimiento asignadas al agente. Lista vacía para quitarlas todas.",
                    "example": []
                  },
                  "kb_top_k": {
                    "type": "number",
                    "description": "Cuántos fragmentos de la base de conocimiento se recuperan por turno.",
                    "example": 10
                  },
                  "kb_min_score": {
                    "type": "number",
                    "description": "Corte de similitud de la búsqueda. Está calibrado con lenguaje HABLADO: subirlo pierde datos que sí están.",
                    "example": 10
                  },
                  "kb_instruction": {
                    "type": "string",
                    "description": "Guía para construir la búsqueda en la base de conocimiento.",
                    "example": "texto de ejemplo"
                  },
                  "silence_reminder_sec": {
                    "type": "number",
                    "description": "Segundos de silencio antes de que el agente pregunte si sigue ahí.",
                    "example": 10
                  },
                  "silence_hangup_sec": {
                    "type": "number",
                    "description": "Segundos de silencio tras los que cuelga.",
                    "example": 10
                  },
                  "end_call_enabled": {
                    "type": "boolean",
                    "description": "Si el agente puede colgar él mismo al terminar.",
                    "example": true
                  },
                  "max_duration_sec": {
                    "type": "number",
                    "description": "Duración máxima de la llamada. Al llegar, se corta.",
                    "example": 10
                  },
                  "transfer_mode": {
                    "type": "string",
                    "enum": [
                      "none",
                      "phone",
                      "pending_request",
                      "phone_or_pending_request"
                    ],
                    "description": "Cómo pasa la llamada a una persona en un agente de prompt único.",
                    "example": "none"
                  },
                  "transfer_e164": {
                    "type": "string",
                    "description": "Número al que pasa la llamada, en formato E.164.",
                    "example": "texto de ejemplo"
                  },
                  "transfer_message": {
                    "type": "string",
                    "description": "Frase que se dice justo antes de pasar la llamada.",
                    "example": "texto de ejemplo"
                  },
                  "cold_transfer_mode": {
                    "type": "string",
                    "enum": [
                      "sip_refer",
                      "sip_invite"
                    ],
                    "description": "Cómo se entrega la llamada: se la damos al operador y salimos, o hacemos de puente.",
                    "example": "sip_refer"
                  },
                  "responsiveness": {
                    "type": "number",
                    "description": "Cuánto tarda en contestar tras la última palabra. Alto responde antes.",
                    "example": 10
                  },
                  "interruption_sensitivity": {
                    "type": "number",
                    "description": "Facilidad para cortarle. Bajo aguanta ruido de fondo; alto se corta enseguida.",
                    "example": 10
                  },
                  "enable_backchannel": {
                    "type": "boolean",
                    "description": "Si el agente asiente mientras el otro habla (\"ajá\", \"claro\").",
                    "example": true
                  },
                  "backchannel_frequency": {
                    "type": "number",
                    "description": "Cuánto asiente. Alto asiente cada pocas palabras.",
                    "example": 10
                  },
                  "backchannel_words": {
                    "type": "array",
                    "description": "Palabras con las que asiente.",
                    "example": []
                  },
                  "post_call_analysis": {
                    "type": "array",
                    "description": "Campos que se extraen solos de cada llamada al terminar, además del resumen.",
                    "example": []
                  },
                  "ai_disclosure": {
                    "type": "boolean",
                    "description": "Si el saludo dice que es un asistente virtual. Informar es responsabilidad del cliente.",
                    "example": true
                  },
                  "pii_categories": {
                    "type": "array",
                    "description": "Datos personales que se BORRAN de la transcripción y del resumen al colgar.",
                    "example": []
                  },
                  "voicemail_option": {
                    "type": "object",
                    "description": "Qué hace en un saliente si salta el contestador. Sin esto, le habla como a una persona.",
                    "example": {}
                  },
                  "voice_model": {
                    "type": "string",
                    "enum": [
                      "eleven_turbo_v2",
                      "eleven_flash_v2",
                      "eleven_turbo_v2_5",
                      "eleven_flash_v2_5",
                      "eleven_multilingual_v2",
                      "eleven_v3",
                      "sonic-3",
                      "sonic-3-latest",
                      "sonic-3.5"
                    ],
                    "description": "Modelo de síntesis. Solo se toca para más calidad o menos latencia.",
                    "example": "eleven_turbo_v2"
                  },
                  "voice_speed": {
                    "type": "number",
                    "description": "Velocidad del habla. 1 es la normal.",
                    "example": 10
                  },
                  "voice_temperature": {
                    "type": "number",
                    "description": "Expresividad de la voz. Bajo suena más estable; alto, más variable.",
                    "example": 10
                  },
                  "llm_temperature": {
                    "type": "number",
                    "description": "Cuánto se aparta el modelo de la respuesta más probable.",
                    "example": 10
                  },
                  "background_sound": {
                    "type": "string",
                    "enum": [
                      "office"
                    ],
                    "description": "Ambiente de fondo para que la llamada no suene aséptica. null, ninguno.",
                    "example": "office"
                  },
                  "background_sound_volume": {
                    "type": "number",
                    "description": "Cuánto se oye ese ambiente. Solo aplica si hay uno puesto.",
                    "example": 10
                  },
                  "thinking_sound_volume": {
                    "type": "number",
                    "example": 10
                  },
                  "normalize_for_speech": {
                    "type": "boolean",
                    "description": "Convierte cifras y horas a como se dicen en voz alta. Viene encendido.",
                    "example": true
                  },
                  "language": {
                    "type": "string",
                    "description": "Idioma en el que atiende las llamadas (es, en, fr). Es del agente, no del panel.",
                    "example": "texto de ejemplo"
                  },
                  "volume": {
                    "type": "number",
                    "description": "Volumen de la voz del agente.",
                    "example": 10
                  },
                  "fallback_voice_ids": {
                    "type": "array",
                    "description": "Voces de reserva si su proveedor no da audio. Tienen que ser de OTRO proveedor.",
                    "example": []
                  },
                  "enable_dynamic_responsiveness": {
                    "type": "boolean",
                    "description": "Ajusta solo la rapidez de respuesta según cómo vaya la conversación.",
                    "example": true
                  },
                  "enable_dynamic_voice_speed": {
                    "type": "boolean",
                    "description": "Ajusta sola la velocidad del habla durante la llamada.",
                    "example": true
                  },
                  "keypad": {
                    "type": "object",
                    "description": "Las teclas del teléfono: recibir las que marque quien llama (encendido de fábrica) y dejar que el agente marque.",
                    "example": {}
                  },
                  "denoising_mode": {
                    "type": "string",
                    "enum": [
                      "no-denoise",
                      "noise-cancellation",
                      "noise-and-background-speech-cancellation"
                    ],
                    "description": "Limpieza del audio que OYE el agente, no del que oye quien llama.",
                    "example": "no-denoise"
                  },
                  "boosted_keywords": {
                    "type": "array",
                    "description": "Palabras que cuestan de transcribir y conviene reforzar (marcas, apellidos).",
                    "example": []
                  },
                  "pronunciation_dictionary": {
                    "type": "array",
                    "description": "Cómo se pronuncian palabras concretas.",
                    "example": []
                  },
                  "behavior": {
                    "type": "object",
                    "description": "Interruptores de conducta: no inventar datos, repetir para confirmar, pedir deletreo…",
                    "example": {}
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo",
                "prompt": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/write_agent_prompt": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Regenera el prompt completo de un agente existente a partir de los datos del negocio y lo guarda en el borrador.",
        "operationId": "write_agent_prompt",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "business_name": {
                    "type": "string",
                    "description": "Nombre real del negocio. Se usa en el saludo y en el prompt.",
                    "example": "texto de ejemplo"
                  },
                  "summary": {
                    "type": "string",
                    "description": "A qué se dedica el negocio, en una frase. Se usa para generar el prompt.",
                    "example": "texto de ejemplo"
                  },
                  "services": {
                    "type": "array",
                    "description": "Servicios del negocio. Alimentan el prompt y lo que el agente sabe ofrecer.",
                    "example": []
                  },
                  "transfer": {
                    "type": "boolean",
                    "description": "Si el agente debe poder pasar la llamada a una persona.",
                    "example": true
                  },
                  "template_key": {
                    "type": "string",
                    "description": "Plantilla de sector de la que partir. Las devuelve list_agent_templates.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "business_name": "texto de ejemplo",
                "summary": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/get_agent_latency": {
      "post": {
        "tags": [
          "calls"
        ],
        "summary": "Desglosa la latencia de las últimas llamadas de un agente, de punta a punta y por componente.",
        "operationId": "get_agent_latency",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "calls": {
                    "type": "number",
                    "description": "Cuántas llamadas recientes se miran para el cálculo.",
                    "example": 10
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/get_analytics": {
      "post": {
        "tags": [
          "calls"
        ],
        "summary": "Devuelve la analítica del workspace: totales, por estado, por dirección, por hora y duración media.",
        "operationId": "get_analytics",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/get_call": {
      "post": {
        "tags": [
          "calls"
        ],
        "summary": "Devuelve el detalle de una llamada: resumen, transcripción, eventos y funciones ejecutadas.",
        "operationId": "get_call",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "call_id": {
                    "type": "string",
                    "description": "Id de la llamada. Lo devuelve list_calls.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "call_id"
                ]
              },
              "example": {
                "call_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/get_concurrency": {
      "post": {
        "tags": [
          "calls"
        ],
        "summary": "Devuelve cuántas llamadas hay en curso y cuántas líneas quedan libres, para autorregular los disparos.",
        "operationId": "get_concurrency",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_calls": {
      "post": {
        "tags": [
          "calls"
        ],
        "summary": "Devuelve las llamadas recientes, filtrables por estado, dirección y teléfono. Hasta 50 por petición.",
        "operationId": "list_calls",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "Filtra por cómo acabó la llamada.",
                    "example": "texto de ejemplo"
                  },
                  "direction": {
                    "type": "string",
                    "enum": [
                      "inbound",
                      "outbound"
                    ],
                    "description": "Si la llamada la recibió el agente o la hizo él.",
                    "example": "inbound"
                  },
                  "phone": {
                    "type": "string",
                    "description": "Fragmento del teléfono de quien llamó, para filtrar.",
                    "example": "texto de ejemplo"
                  },
                  "limit": {
                    "type": "number",
                    "description": "Máximo de resultados que devuelve.",
                    "example": 10
                  }
                }
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/start_outbound_call": {
      "post": {
        "tags": [
          "calls"
        ],
        "summary": "Lanza una llamada saliente. Las variables llegan por llamada y se interpolan en el prompt y las funciones.",
        "operationId": "start_outbound_call",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to_number": {
                    "type": "string",
                    "description": "Número al que llamar, en formato E.164 (+34600111222).",
                    "example": "+34600111222"
                  },
                  "agent_id": {
                    "type": "string",
                    "description": "Agente que llama. Si se omite, se usa el agente saliente asignado al número.",
                    "example": "cmk1a2b3c..."
                  },
                  "variables": {
                    "type": "object",
                    "description": "Valores propios de esta llamada. Se interpolan en el prompt y en las funciones.",
                    "example": {}
                  },
                  "idempotency_key": {
                    "type": "string",
                    "description": "Clave propia para que reintentar la misma petición no dispare dos llamadas.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "to_number"
                ]
              },
              "example": {
                "to_number": "+34600111222",
                "agent_id": "cmk1a2b3c...",
                "variables": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/set_inbound_concurrency_reservation": {
      "post": {
        "tags": [
          "calls"
        ],
        "summary": "Guarda N líneas simultáneas para el teléfono entrante: las salientes y el canal web no podrán ocuparlas.",
        "operationId": "set_inbound_concurrency_reservation",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reserved": {
                    "type": "number",
                    "example": 10
                  }
                },
                "required": [
                  "reserved"
                ]
              },
              "example": {
                "reserved": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_phone_numbers": {
      "post": {
        "tags": [
          "numbers"
        ],
        "summary": "Devuelve los números del workspace con sus agentes asignados, países permitidos y estado.",
        "operationId": "list_phone_numbers",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/check_phone_number": {
      "post": {
        "tags": [
          "numbers"
        ],
        "summary": "Diagnostica un número: si está conectado, si tiene agente entrante y si ese agente está publicado.",
        "operationId": "check_phone_number",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number_id": {
                    "type": "string",
                    "description": "Id del número. Lo devuelve list_phone_numbers.",
                    "example": "cmk1a2b3c..."
                  },
                  "e164": {
                    "type": "string",
                    "description": "Número en formato E.164, con prefijo de país (+34600111222).",
                    "example": "+34600111222"
                  }
                }
              },
              "example": {
                "phone_number_id": "cmk1a2b3c...",
                "e164": "+34600111222"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/import_phone_number": {
      "post": {
        "tags": [
          "numbers"
        ],
        "summary": "Importa un número que ya tienes (Twilio, Telnyx o SIP) para que Lera atienda sus llamadas.",
        "operationId": "import_phone_number",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "e164": {
                    "type": "string",
                    "description": "Número en formato E.164, con prefijo de país (+34600111222).",
                    "example": "+34600111222"
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "twilio",
                      "telnyx",
                      "sip",
                      "custom"
                    ],
                    "description": "De dónde viene el número: Twilio, Telnyx o una centralita SIP.",
                    "example": "twilio"
                  },
                  "label": {
                    "type": "string",
                    "description": "Alias para reconocer el número en el panel.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "e164"
                ]
              },
              "example": {
                "e164": "+34600111222",
                "provider": "twilio",
                "label": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/assign_inbound_agent": {
      "post": {
        "tags": [
          "numbers"
        ],
        "summary": "Asigna qué agente atiende las llamadas entrantes de un número. Pasa null para dejarlo sin agente.",
        "operationId": "assign_inbound_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number_id": {
                    "type": "string",
                    "description": "Id del número. Lo devuelve list_phone_numbers.",
                    "example": "cmk1a2b3c..."
                  },
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "phone_number_id"
                ]
              },
              "example": {
                "phone_number_id": "cmk1a2b3c...",
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/assign_outbound_agent": {
      "post": {
        "tags": [
          "numbers"
        ],
        "summary": "Asigna qué agente hace las llamadas salientes desde un número. Pasa null para dejarlo sin agente.",
        "operationId": "assign_outbound_agent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number_id": {
                    "type": "string",
                    "description": "Id del número. Lo devuelve list_phone_numbers.",
                    "example": "cmk1a2b3c..."
                  },
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "phone_number_id"
                ]
              },
              "example": {
                "phone_number_id": "cmk1a2b3c...",
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/reconnect_phone_number": {
      "post": {
        "tags": [
          "numbers"
        ],
        "summary": "Reintenta conectar un número a la entrada de llamadas. Úsalo si el diagnóstico dice que no está conectado.",
        "operationId": "reconnect_phone_number",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number_id": {
                    "type": "string",
                    "description": "Id del número. Lo devuelve list_phone_numbers.",
                    "example": "cmk1a2b3c..."
                  },
                  "e164": {
                    "type": "string",
                    "description": "Número en formato E.164, con prefijo de país (+34600111222).",
                    "example": "+34600111222"
                  }
                }
              },
              "example": {
                "phone_number_id": "cmk1a2b3c...",
                "e164": "+34600111222"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/check_transfers": {
      "post": {
        "tags": [
          "flow"
        ],
        "summary": "Diagnostica qué derivaciones puede hacer de verdad esta cuenta. Úsalo antes de prometer una a nadie.",
        "operationId": "check_transfers",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                }
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/get_agent_flow": {
      "post": {
        "tags": [
          "flow"
        ],
        "summary": "Devuelve el flujo por nodos del borrador junto a las funciones disponibles. Léelo antes de editarlo.",
        "operationId": "get_agent_flow",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/attach_function_to_node": {
      "post": {
        "tags": [
          "flow"
        ],
        "summary": "Ofrece una función en una fase concreta del flujo. En un agente de flujo, crear la función no basta.",
        "operationId": "attach_function_to_node",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "node_id": {
                    "type": "string",
                    "description": "Id del nodo del flujo. Lo devuelve get_agent_flow.",
                    "example": "cmk1a2b3c..."
                  },
                  "function_name": {
                    "type": "string",
                    "description": "Nombre de la función del agente. Lo devuelve list_agent_functions.",
                    "example": "texto de ejemplo"
                  },
                  "run_on_enter": {
                    "type": "boolean",
                    "description": "Ejecutar la función al ENTRAR en el nodo, sin esperar a que el modelo la pida.",
                    "example": true
                  }
                },
                "required": [
                  "agent_id",
                  "node_id",
                  "function_name"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "node_id": "cmk1a2b3c...",
                "function_name": "texto de ejemplo",
                "run_on_enter": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/patch_node": {
      "post": {
        "tags": [
          "flow"
        ],
        "summary": "Cambia un solo nodo del flujo sin tocar el resto: su prompt, su tipo, su modelo o sus bases de conocimiento.",
        "operationId": "patch_node",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "node_id": {
                    "type": "string",
                    "description": "Id del nodo del flujo. Lo devuelve get_agent_flow.",
                    "example": "cmk1a2b3c..."
                  },
                  "prompt": {
                    "type": "string",
                    "description": "Instrucciones del agente: qué hace, qué pregunta y cómo responde.",
                    "example": "texto de ejemplo"
                  },
                  "static_text": {
                    "type": "string",
                    "description": "Frase fija que dice el nodo tal cual, sin generar. Es la opción más rápida.",
                    "example": "texto de ejemplo"
                  },
                  "instruction_mode": {
                    "type": "string",
                    "enum": [
                      "prompt",
                      "static"
                    ],
                    "description": "Si manda la frase fija o el prompt del nodo.",
                    "example": "prompt"
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "conversation",
                      "subagent"
                    ],
                    "description": "Tipo del nodo. Solo entre diálogo con herramientas y diálogo limpio.",
                    "example": "conversation"
                  },
                  "name": {
                    "type": "string",
                    "description": "Nuevo nombre del nodo. Se inyecta en el prompt, así que escríbelo bien y con tildes.",
                    "example": "texto de ejemplo"
                  },
                  "llm_model": {
                    "type": "string",
                    "description": "Modelo solo para este nodo. Sirve para poner uno más capaz donde de verdad hace falta.",
                    "example": "texto de ejemplo"
                  },
                  "is_global": {
                    "type": "boolean",
                    "description": "Hace el nodo alcanzable desde cualquier fase sin necesidad de una flecha.",
                    "example": true
                  },
                  "global_condition": {
                    "type": "string",
                    "description": "Cuándo se salta a ese nodo global, dicho desde lo que dice quien llama.",
                    "example": "texto de ejemplo"
                  },
                  "global_cooldown": {
                    "type": "number",
                    "description": "Fases que tienen que pasar antes de que ese global pueda volver a dispararse.",
                    "example": 10
                  },
                  "knowledge_base_ids": {
                    "type": "array",
                    "description": "Ids de las bases de conocimiento asignadas al agente. Lista vacía para quitarlas todas.",
                    "example": []
                  },
                  "kb_config": {
                    "type": "object",
                    "description": "Ajuste fino de la búsqueda solo en este nodo. Pisa el del agente campo a campo.",
                    "example": {}
                  },
                  "thinking_sound": {
                    "type": "boolean",
                    "example": true
                  }
                },
                "required": [
                  "agent_id",
                  "node_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "node_id": "cmk1a2b3c...",
                "prompt": "texto de ejemplo",
                "static_text": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/patch_transfer": {
      "post": {
        "tags": [
          "flow"
        ],
        "summary": "Cambia cómo deriva un agente: destino, extensión, si entrega o presenta el caso, y qué oye quien espera.",
        "operationId": "patch_transfer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "node_id": {
                    "type": "string",
                    "description": "Id del nodo del flujo. Lo devuelve get_agent_flow.",
                    "example": "cmk1a2b3c..."
                  },
                  "target": {
                    "type": "string",
                    "description": "A dónde va la llamada: un número E.164 o una dirección SIP de la centralita.",
                    "example": "texto de ejemplo"
                  },
                  "destination_prompt": {
                    "type": "string",
                    "description": "En vez de un destino fijo, describe a dónde va cada caso y el modelo elige. Excluyente con target.",
                    "example": "texto de ejemplo"
                  },
                  "extension": {
                    "type": "string",
                    "description": "Extensión que se teclea al descolgar. Solo funciona haciendo de puente.",
                    "example": "texto de ejemplo"
                  },
                  "extra_targets": {
                    "type": "array",
                    "description": "Destinos de respaldo si el primero no coge.",
                    "example": []
                  },
                  "announce_next_target": {
                    "type": "boolean",
                    "description": "Si avisa a quien llama antes de probar con el siguiente destino.",
                    "example": true
                  },
                  "next_target_message": {
                    "type": "string",
                    "description": "Frase de ese aviso. Vacía, la redacta el agente.",
                    "example": "texto de ejemplo"
                  },
                  "transfer_type": {
                    "type": "string",
                    "enum": [
                      "cold",
                      "warm",
                      "agentic"
                    ],
                    "description": "Si se entrega la llamada o se presenta el caso antes de pasarla.",
                    "example": "cold"
                  },
                  "cold_transfer_mode": {
                    "type": "string",
                    "enum": [
                      "sip_refer",
                      "sip_invite"
                    ],
                    "description": "Cómo se entrega la llamada: se la damos al operador y salimos, o hacemos de puente.",
                    "example": "sip_refer"
                  },
                  "caller_id": {
                    "type": "string",
                    "enum": [
                      "trunk",
                      "caller"
                    ],
                    "description": "Qué número ve quien recibe la llamada transferida.",
                    "example": "trunk"
                  },
                  "ring_duration_ms": {
                    "type": "number",
                    "description": "Cuánto suena el destino antes de darlo por fallido.",
                    "example": 1000
                  },
                  "speak_during_execution": {
                    "type": "boolean",
                    "description": "Si el agente dice algo mientras la función se ejecuta, para que la espera no suene a silencio.",
                    "example": true
                  },
                  "transfer_message": {
                    "type": "string",
                    "description": "Frase que se dice justo antes de pasar la llamada.",
                    "example": "texto de ejemplo"
                  },
                  "human_detection": {
                    "type": "boolean",
                    "description": "Comprobar que ha descolgado una persona antes de presentarle el caso.",
                    "example": true
                  },
                  "hold_music": {
                    "type": "string",
                    "enum": [
                      "none",
                      "hold_music",
                      "office_ambience",
                      "keyboard_typing"
                    ],
                    "description": "Qué oye quien llama mientras espera la transferencia.",
                    "example": "none"
                  },
                  "handoff_private": {
                    "type": "string",
                    "description": "Lo que el agente le cuenta a la persona ANTES de pasarle la llamada.",
                    "example": "texto de ejemplo"
                  },
                  "handoff_public": {
                    "type": "string",
                    "description": "Lo que se dice delante de quien llama al hacer el traspaso.",
                    "example": "texto de ejemplo"
                  },
                  "allow_unvalidated_target": {
                    "type": "boolean",
                    "description": "Aceptar un destino que no es número ni SIP, como una extensión suelta de su centralita.",
                    "example": true
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "node_id": "cmk1a2b3c...",
                "target": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/update_agent_flow": {
      "post": {
        "tags": [
          "flow"
        ],
        "summary": "Reemplaza el grafo completo del borrador y pone el agente en modo flujo. Para un solo nodo, usa patch_node.",
        "operationId": "update_agent_flow",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "conversation_flow": {
                    "type": "object",
                    "description": "El grafo completo: nodo inicial y lista de nodos. Reemplaza el flujo anterior.",
                    "example": {}
                  }
                },
                "required": [
                  "agent_id",
                  "conversation_flow"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "conversation_flow": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/detach_function_from_node": {
      "post": {
        "tags": [
          "flow"
        ],
        "summary": "Deja de ofrecer una función en ese nodo. No la borra del agente.",
        "operationId": "detach_function_from_node",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "node_id": {
                    "type": "string",
                    "description": "Id del nodo del flujo. Lo devuelve get_agent_flow.",
                    "example": "cmk1a2b3c..."
                  },
                  "function_name": {
                    "type": "string",
                    "description": "Nombre de la función del agente. Lo devuelve list_agent_functions.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "node_id",
                  "function_name"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "node_id": "cmk1a2b3c...",
                "function_name": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_agent_functions": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Devuelve las funciones personalizadas de un agente con su método, su URL y sus parámetros.",
        "operationId": "list_agent_functions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_calcom_event_types": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Lista los tipos de evento de una cuenta de Cal.com para elegir cuál usar. Solo lee: no guarda nada.",
        "operationId": "list_calcom_event_types",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "api_key": {
                    "type": "string",
                    "description": "Clave de Cal.com del usuario. No se devuelve nunca al consultar.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "api_key"
                ]
              },
              "example": {
                "api_key": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_calendar_functions": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Devuelve el conector de calendario de un agente y su tipo de evento. Nunca devuelve la clave de Cal.com.",
        "operationId": "list_calendar_functions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/add_agent_function": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Añade una función: durante la llamada el agente hace una petición firmada a tu URL. Máximo 10 por agente.",
        "operationId": "add_agent_function",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "description": "Identificador de la función: minúsculas, sin espacios.",
                    "example": "texto de ejemplo"
                  },
                  "description": {
                    "type": "string",
                    "description": "Cuándo debe usar el agente esta función.",
                    "example": "texto de ejemplo"
                  },
                  "url": {
                    "type": "string",
                    "description": "URL de tu sistema. Tiene que ser https y accesible desde fuera.",
                    "example": "https://tu-sistema.example.com/consultar"
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "GET",
                      "POST",
                      "PUT",
                      "PATCH",
                      "DELETE"
                    ],
                    "description": "Método HTTP con el que se llama a tu URL. Por defecto POST.",
                    "example": "GET"
                  },
                  "headers": {
                    "type": "array",
                    "description": "Cabeceras propias de la petición. No se admiten content-type ni las que empiezan por x-lera-.",
                    "example": []
                  },
                  "parameters": {
                    "type": "array",
                    "description": "Datos que el agente recoge en la llamada y te manda en la petición.",
                    "example": []
                  },
                  "speak_during_execution": {
                    "type": "boolean",
                    "description": "Si el agente dice algo mientras la función se ejecuta, para que la espera no suene a silencio.",
                    "example": true
                  },
                  "wait_message": {
                    "type": "string",
                    "description": "Frase que dice el agente mientras la función se ejecuta. Vacío usa la del motor.",
                    "example": "texto de ejemplo"
                  },
                  "wait_after_ms": {
                    "type": "number",
                    "description": "Milisegundos que debe tardar la función antes de decir la frase de espera. Recomendado 1000.",
                    "example": 1000
                  },
                  "thinking_sound": {
                    "type": "boolean",
                    "example": true
                  },
                  "speak_after_execution": {
                    "type": "boolean",
                    "description": "Si el agente habla después de ejecutarla. Con false el turno cierra, salvo que falle.",
                    "example": true
                  },
                  "refrescar_cuando": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "mock_response": {
                    "type": "string",
                    "description": "Respuesta de prueba para el panel. En una llamada real se llama a tu URL.",
                    "example": "texto de ejemplo"
                  },
                  "response_captures": {
                    "type": "array",
                    "description": "Campos de tu respuesta que se guardan como variables para usarlos después.",
                    "example": []
                  },
                  "timeout_ms": {
                    "type": "number",
                    "description": "Tiempo máximo de espera a tu sistema, en milisegundos.",
                    "example": 1000
                  }
                },
                "required": [
                  "agent_id",
                  "name",
                  "description",
                  "url"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo",
                "description": "texto de ejemplo",
                "url": "https://tu-sistema.example.com/consultar",
                "method": "GET",
                "headers": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/add_agent_message": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Da al agente la capacidad de mandar un SMS, un correo o un WhatsApp durante la llamada. Hoy solo el correo está disponible, y lo enviamos nosotros. SMS y WhatsApp aún no tienen conector.",
        "operationId": "add_agent_message",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "channel": {
                    "type": "string",
                    "enum": [
                      "sms",
                      "email",
                      "whatsapp"
                    ],
                    "example": "sms"
                  },
                  "description": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "body_mode": {
                    "type": "string",
                    "enum": [
                      "static",
                      "prompt",
                      "template"
                    ],
                    "example": "static"
                  },
                  "body": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "subject": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "template_key": {
                    "type": "string",
                    "description": "Plantilla de sector de la que partir. Las devuelve list_agent_templates.",
                    "example": "texto de ejemplo"
                  },
                  "to": {
                    "type": "string",
                    "enum": [
                      "caller",
                      "variable",
                      "fixed"
                    ],
                    "example": "caller"
                  },
                  "to_var": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "to_fixed": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "name",
                  "channel",
                  "body"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo",
                "channel": "sms",
                "body": "texto de ejemplo",
                "description": "texto de ejemplo",
                "body_mode": "static"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/connect_calendar": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Conecta Cal.com a un agente para consultar huecos y reservar citas durante la llamada.",
        "operationId": "connect_calendar",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "api_key": {
                    "type": "string",
                    "description": "Clave de Cal.com del usuario. No se devuelve nunca al consultar.",
                    "example": "texto de ejemplo"
                  },
                  "event_type_id": {
                    "type": "string",
                    "description": "Tipo de evento de Cal.com que se reserva. Lo devuelve list_calcom_event_types.",
                    "example": "cmk1a2b3c..."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "Zona horaria con la que se leen los huecos y se reservan las citas.",
                    "example": "texto de ejemplo"
                  },
                  "availability_wait_message": {
                    "type": "string",
                    "description": "Frase mientras consulta huecos. Vacía usa la del motor, en el idioma del agente.",
                    "example": "texto de ejemplo"
                  },
                  "book_wait_message": {
                    "type": "string",
                    "description": "Frase mientras reserva. Vacía usa la del motor.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "api_key",
                  "event_type_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "api_key": "texto de ejemplo",
                "event_type_id": "cmk1a2b3c...",
                "timezone": "texto de ejemplo",
                "availability_wait_message": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/set_post_call_actions": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Define qué pasa cuando la llamada termina: mandar un mensaje o llamar a una función tuya, con una condición opcional sobre el análisis.",
        "operationId": "set_post_call_actions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "actions": {
                    "type": "array",
                    "example": []
                  }
                },
                "required": [
                  "agent_id",
                  "actions"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "actions": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/update_agent_function": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Edita una función por su nombre. Solo cambia lo que pasas; para renombrarla, bórrala y créala de nuevo.",
        "operationId": "update_agent_function",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "description": "Nombre de la función a editar.",
                    "example": "texto de ejemplo"
                  },
                  "description": {
                    "type": "string",
                    "description": "Cuándo debe usar el agente esta función.",
                    "example": "texto de ejemplo"
                  },
                  "url": {
                    "type": "string",
                    "description": "URL de tu sistema. Tiene que ser https y accesible desde fuera.",
                    "example": "https://tu-sistema.example.com/consultar"
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "GET",
                      "POST",
                      "PUT",
                      "PATCH",
                      "DELETE"
                    ],
                    "description": "Método HTTP con el que se llama a tu URL. Por defecto POST.",
                    "example": "GET"
                  },
                  "headers": {
                    "type": "array",
                    "description": "Cabeceras propias de la petición. No se admiten content-type ni las que empiezan por x-lera-.",
                    "example": []
                  },
                  "parameters": {
                    "type": "array",
                    "description": "Datos que el agente recoge en la llamada y te manda en la petición.",
                    "example": []
                  },
                  "speak_during_execution": {
                    "type": "boolean",
                    "description": "Si el agente dice algo mientras la función se ejecuta, para que la espera no suene a silencio.",
                    "example": true
                  },
                  "wait_message": {
                    "type": "string",
                    "description": "Frase que dice el agente mientras la función se ejecuta. Vacío usa la del motor.",
                    "example": "texto de ejemplo"
                  },
                  "wait_after_ms": {
                    "type": "number",
                    "description": "Milisegundos que debe tardar la función antes de decir la frase de espera. Recomendado 1000.",
                    "example": 1000
                  },
                  "thinking_sound": {
                    "type": "boolean",
                    "example": true
                  },
                  "speak_after_execution": {
                    "type": "boolean",
                    "description": "Si el agente habla después de ejecutarla. Con false el turno cierra, salvo que falle.",
                    "example": true
                  },
                  "refrescar_cuando": {
                    "type": "string",
                    "example": "texto de ejemplo"
                  },
                  "mock_response": {
                    "type": "string",
                    "description": "Respuesta de prueba para el panel. En una llamada real se llama a tu URL.",
                    "example": "texto de ejemplo"
                  },
                  "response_captures": {
                    "type": "array",
                    "description": "Campos de tu respuesta que se guardan como variables para usarlos después.",
                    "example": []
                  },
                  "timeout_ms": {
                    "type": "number",
                    "description": "Tiempo máximo de espera a tu sistema, en milisegundos.",
                    "example": 1000
                  }
                },
                "required": [
                  "agent_id",
                  "name"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo",
                "description": "texto de ejemplo",
                "url": "https://tu-sistema.example.com/consultar"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/remove_agent_function": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Elimina una función del agente y la quita de cualquier fase del flujo que la usara.",
        "operationId": "remove_agent_function",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "description": "Nombre de la función a eliminar.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "name"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/remove_calendar_functions": {
      "post": {
        "tags": [
          "functions"
        ],
        "summary": "Desconecta el calendario de un agente. Acuérdate de publicar después.",
        "operationId": "remove_calendar_functions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/discover_site": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Descubre las páginas de un sitio por su sitemap para decidir cuáles añadir. Solo lee: no crea nada.",
        "operationId": "discover_site",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "URL de tu sistema. Tiene que ser https y accesible desde fuera.",
                    "example": "https://tu-sistema.example.com/consultar"
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://tu-sistema.example.com/consultar"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_knowledge": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Devuelve las entradas de conocimiento del proyecto: lo que el agente sabe responder del negocio.",
        "operationId": "list_knowledge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_knowledge_bases": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Devuelve las bases de conocimiento del proyecto con su estado y sus documentos.",
        "operationId": "list_knowledge_bases",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/add_knowledge": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Añade una entrada de conocimiento. Solo hacen falta un título y la respuesta.",
        "operationId": "add_knowledge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "description": "Título con el que se identifica, y por el que se busca.",
                    "example": "texto de ejemplo"
                  },
                  "answer": {
                    "type": "string",
                    "description": "La información que el agente da al responder.",
                    "example": "texto de ejemplo"
                  },
                  "keywords": {
                    "type": "array",
                    "description": "Palabras por las que se encuentra esta entrada.",
                    "example": []
                  }
                },
                "required": [
                  "title",
                  "answer"
                ]
              },
              "example": {
                "title": "texto de ejemplo",
                "answer": "texto de ejemplo",
                "keywords": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/add_knowledge_source": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Añade un documento a una base: texto o una página web, que se relee sola cada 12 horas.",
        "operationId": "add_knowledge_source",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "knowledge_base_id": {
                    "type": "string",
                    "description": "Id de la base de conocimiento. Lo devuelve list_knowledge_bases.",
                    "example": "cmk1a2b3c..."
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "text",
                      "url"
                    ],
                    "description": "Si el documento es texto pegado o una página web.",
                    "example": "text"
                  },
                  "title": {
                    "type": "string",
                    "description": "Título con el que se identifica, y por el que se busca.",
                    "example": "texto de ejemplo"
                  },
                  "text": {
                    "type": "string",
                    "description": "El contenido pegado, cuando el documento es texto.",
                    "example": "texto de ejemplo"
                  },
                  "url": {
                    "type": "string",
                    "description": "URL de tu sistema. Tiene que ser https y accesible desde fuera.",
                    "example": "https://tu-sistema.example.com/consultar"
                  }
                },
                "required": [
                  "knowledge_base_id",
                  "kind"
                ]
              },
              "example": {
                "knowledge_base_id": "cmk1a2b3c...",
                "kind": "text",
                "title": "texto de ejemplo",
                "text": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/analyze_website": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Lee la web del negocio y extrae nombre, actividad, servicios, preguntas frecuentes, tono y un saludo sugerido.",
        "operationId": "analyze_website",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "URL de tu sistema. Tiene que ser https y accesible desde fuera.",
                    "example": "https://tu-sistema.example.com/consultar"
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://tu-sistema.example.com/consultar"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/create_knowledge_base": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Crea una base de conocimiento vacía. Después se le añaden documentos y se asigna a un agente.",
        "operationId": "create_knowledge_base",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nombre de la base de conocimiento.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/update_knowledge": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Edita una entrada de conocimiento por su id. Cambia solo los campos que pasas.",
        "operationId": "update_knowledge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Id de la entrada de conocimiento. Lo devuelve list_knowledge.",
                    "example": "cmk1a2b3c..."
                  },
                  "title": {
                    "type": "string",
                    "description": "Título con el que se identifica, y por el que se busca.",
                    "example": "texto de ejemplo"
                  },
                  "answer": {
                    "type": "string",
                    "description": "La información que el agente da al responder.",
                    "example": "texto de ejemplo"
                  },
                  "keywords": {
                    "type": "array",
                    "description": "Palabras por las que se encuentra esta entrada.",
                    "example": []
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "published"
                    ],
                    "description": "Si la entrada está publicada o guardada como borrador.",
                    "example": "draft"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "example": {
                "id": "cmk1a2b3c...",
                "title": "texto de ejemplo",
                "answer": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/remove_knowledge": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Elimina una entrada de conocimiento por su id.",
        "operationId": "remove_knowledge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Id de la entrada de conocimiento. Lo devuelve list_knowledge.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "id"
                ]
              },
              "example": {
                "id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/remove_knowledge_source": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Quita un documento de una base y borra sus fragmentos, así que el agente deja de poder responder con él.",
        "operationId": "remove_knowledge_source",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "knowledge_base_id": {
                    "type": "string",
                    "description": "Id de la base de conocimiento. Lo devuelve list_knowledge_bases.",
                    "example": "cmk1a2b3c..."
                  },
                  "source_id": {
                    "type": "string",
                    "description": "Id del documento dentro de la base. Lo devuelve list_knowledge_bases.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "knowledge_base_id",
                  "source_id"
                ]
              },
              "example": {
                "knowledge_base_id": "cmk1a2b3c...",
                "source_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/get_pre_call_webhook": {
      "post": {
        "tags": [
          "variables"
        ],
        "summary": "Devuelve la configuración del webhook de pre-llamada. De las cabeceras solo devuelve los nombres.",
        "operationId": "get_pre_call_webhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/add_call_variable": {
      "post": {
        "tags": [
          "variables"
        ],
        "summary": "Añade una variable de llamada, usable como {{nombre}} en el saludo, las instrucciones y las funciones.",
        "operationId": "add_call_variable",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "description": "Nombre de la variable. Se usa como {{nombre}} en el prompt y las funciones.",
                    "example": "texto de ejemplo"
                  },
                  "description": {
                    "type": "string",
                    "description": "Qué contiene la variable, para que el agente sepa usarla.",
                    "example": "texto de ejemplo"
                  },
                  "default_value": {
                    "type": "string",
                    "description": "Valor que toma la variable si la llamada no trae otro.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "name"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo",
                "description": "texto de ejemplo",
                "default_value": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/test_pre_call_webhook": {
      "post": {
        "tags": [
          "variables"
        ],
        "summary": "Dispara el webhook con un número de ejemplo y enseña lo que contesta tu sistema, sin llamar por teléfono.",
        "operationId": "test_pre_call_webhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "from_number": {
                    "type": "string",
                    "description": "Número de ejemplo con el que se dispara la prueba.",
                    "example": "+34600111222"
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "from_number": "+34600111222"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/set_pre_call_webhook": {
      "post": {
        "tags": [
          "variables"
        ],
        "summary": "Configura la URL a la que Lera pregunta quién llama antes de descolgar, para que el saludo ya sepa el nombre.",
        "operationId": "set_pre_call_webhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "url": {
                    "type": "string",
                    "description": "URL de tu sistema. Tiene que ser https y accesible desde fuera.",
                    "example": "https://tu-sistema.example.com/consultar"
                  },
                  "budget_ms": {
                    "type": "number",
                    "description": "Tope TOTAL de espera. Es silencio en la línea: no lo subas sin motivo.",
                    "example": 1000
                  },
                  "channels": {
                    "type": "array",
                    "description": "En qué puertas se pregunta: teléfono entrante, widget web o salientes.",
                    "example": []
                  },
                  "allow": {
                    "type": "array",
                    "description": "Qué se le permite devolver a tu sistema. Por defecto, solo variables.",
                    "example": []
                  },
                  "on_failure": {
                    "type": "string",
                    "enum": [
                      "continue",
                      "reject"
                    ],
                    "description": "Qué pasa si tu endpoint no contesta: atender igual o no atender.",
                    "example": "continue"
                  }
                },
                "required": [
                  "agent_id",
                  "url"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "url": "https://tu-sistema.example.com/consultar",
                "budget_ms": 1000,
                "channels": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/update_call_variable": {
      "post": {
        "tags": [
          "variables"
        ],
        "summary": "Edita una variable de llamada por su nombre. Solo cambia lo que pasas.",
        "operationId": "update_call_variable",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "description": "Nombre de la variable a editar.",
                    "example": "texto de ejemplo"
                  },
                  "description": {
                    "type": "string",
                    "description": "Qué contiene la variable.",
                    "example": "texto de ejemplo"
                  },
                  "default_value": {
                    "type": "string",
                    "description": "Valor que toma la variable si la llamada no trae otro.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "name"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo",
                "description": "texto de ejemplo",
                "default_value": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/remove_call_variable": {
      "post": {
        "tags": [
          "variables"
        ],
        "summary": "Elimina una variable de llamada de un agente.",
        "operationId": "remove_call_variable",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  },
                  "name": {
                    "type": "string",
                    "description": "Nombre de la variable a eliminar.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "agent_id",
                  "name"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c...",
                "name": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/remove_pre_call_webhook": {
      "post": {
        "tags": [
          "variables"
        ],
        "summary": "Quita el webhook de pre-llamada. El agente deja de saber quién llama antes de descolgar.",
        "operationId": "remove_pre_call_webhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string",
                    "description": "Id del agente. Lo devuelve list_agents.",
                    "example": "cmk1a2b3c..."
                  }
                },
                "required": [
                  "agent_id"
                ]
              },
              "example": {
                "agent_id": "cmk1a2b3c..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_optout_numbers": {
      "post": {
        "tags": [
          "optout"
        ],
        "summary": "Devuelve los números excluidos de llamadas salientes.",
        "operationId": "list_optout_numbers",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/add_optout_number": {
      "post": {
        "tags": [
          "optout"
        ],
        "summary": "Excluye un número de las llamadas salientes: el agente no volverá a llamarle nunca.",
        "operationId": "add_optout_number",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "e164": {
                    "type": "string",
                    "description": "Número en formato E.164, con prefijo de país (+34600111222).",
                    "example": "+34600111222"
                  },
                  "reason": {
                    "type": "string",
                    "description": "Por qué se excluye el número. Queda registrado.",
                    "example": "texto de ejemplo"
                  }
                },
                "required": [
                  "e164"
                ]
              },
              "example": {
                "e164": "+34600111222",
                "reason": "texto de ejemplo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/remove_optout_number": {
      "post": {
        "tags": [
          "optout"
        ],
        "summary": "Quita un número de la lista de exclusión, de forma que vuelve a ser llamable.",
        "operationId": "remove_optout_number",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "e164": {
                    "type": "string",
                    "description": "Número en formato E.164, con prefijo de país (+34600111222).",
                    "example": "+34600111222"
                  }
                },
                "required": [
                  "e164"
                ]
              },
              "example": {
                "e164": "+34600111222"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/get_billing_summary": {
      "post": {
        "tags": [
          "account"
        ],
        "summary": "Devuelve el consumo del mes, el saldo y los límites del workspace. En un proyecto hijo, el saldo llega vacío.",
        "operationId": "get_billing_summary",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_integrations": {
      "post": {
        "tags": [
          "account"
        ],
        "summary": "Devuelve las integraciones del proyecto y su estado. Hoy existe el webhook posterior a la llamada.",
        "operationId": "list_integrations",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/list_widget_keys": {
      "post": {
        "tags": [
          "account"
        ],
        "summary": "Devuelve las claves del canal web con sus webs autorizadas y su último uso. Útil para diagnosticar el widget.",
        "operationId": "list_widget_keys",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools/set_post_call_webhook": {
      "post": {
        "tags": [
          "account"
        ],
        "summary": "Define la URL a la que Lera envía cada llamada al cerrarse, con su resumen, su transcripción y los datos extraídos.",
        "operationId": "set_post_call_webhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LeraClient"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "URL de tu sistema. Tiene que ser https y accesible desde fuera.",
                    "example": "https://tu-sistema.example.com/consultar"
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Activar o desactivar el envío sin perder la URL. Por defecto true.",
                    "example": true
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://tu-sistema.example.com/consultar",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devuelve el resultado dentro de result."
          },
          "400": {
            "description": "bad_request"
          },
          "401": {
            "description": "unauthorized"
          },
          "402": {
            "description": "account_read_only"
          },
          "403": {
            "description": "insufficient_scope · workspace_suspended"
          },
          "429": {
            "description": "too_many_requests"
          }
        }
      }
    },
    "/api/v1/tools": {
      "get": {
        "tags": [
          "catalog"
        ],
        "summary": "Devuelve el catalogo de operaciones con su esquema de entrada.",
        "operationId": "catalog",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Catalogo de operaciones."
          },
          "401": {
            "description": "unauthorized"
          }
        }
      }
    },
    "/api/v1/web-calls": {
      "post": {
        "tags": [
          "catalog"
        ],
        "summary": "Abre una llamada por navegador desde tu backend y devuelve el token de sala.",
        "operationId": "web-calls",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "type": "string"
                  },
                  "variables": {
                    "type": "object"
                  }
                },
                "required": [
                  "agent_id"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "call_id, access_token, livekit_url y max_duration_sec."
          },
          "402": {
            "description": "plan_limit_reached"
          },
          "404": {
            "description": "agent_not_found"
          },
          "409": {
            "description": "agent_not_published"
          }
        }
      }
    },
    "/api/v1/partner/clients": {
      "get": {
        "tags": [
          "partner"
        ],
        "summary": "Cada cliente de la cuenta partner con sus minutos y su coste del periodo.",
        "operationId": "partner-clients",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Inicio del periodo, en ISO 8601. Sin el, el mes en curso.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Fin del periodo, en ISO 8601. Exclusivo.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "partner, period y clients."
          },
          "403": {
            "description": "not_a_partner · not_a_partner_root"
          }
        }
      }
    },
    "/api/v1/partner/clients/{workspace_id}": {
      "get": {
        "tags": [
          "partner"
        ],
        "summary": "Un cliente concreto con su consumo del periodo y su actividad de llamadas.",
        "operationId": "partner-client-detail",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "description": "Id del cliente. Sale de GET /api/v1/partner/clients.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Inicio del periodo, en ISO 8601. Sin el, el mes en curso.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Fin del periodo, en ISO 8601. Exclusivo.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "El cliente con minutos, coste, llamadas y ultima llamada."
          },
          "403": {
            "description": "not_a_partner · not_a_partner_root"
          },
          "404": {
            "description": "client_not_found"
          }
        }
      }
    }
  }
}
