{
 "openapi": "3.1.0",
 "info": {
  "title": "Beatrice API",
  "version": "1.0.0-beta",
  "description": "API publica de Beatrice (beta cerrada con invitacion). Autenticacion por llave bk_ en el header Authorization: Bearer bk_... Cuota gratis: 50 peticiones/dia y 10 por minuto por llave. Si registras tus propias llaves de proveedores en Mi cuenta (BYOK), se usan primero y no consumen la cuota del sistema. Esquemas extraidos del codigo de produccion (src/index.ts); existen endpoints adicionales para la app (/v1/work, /v1/feedback, /v1/cicatrices) fuera del alcance de esta spec."
 },
 "servers": [{"url": "https://beatrice-ia.pages.dev"}],
 "security": [{"bearerAuth": []}],
 "components": {
  "securitySchemes": {
   "bearerAuth": {"type": "http", "scheme": "bearer", "description": "Llave bk_ de tu cuenta (se muestra una vez al crearla)."}
  },
  "schemas": {
   "Error": {"type": "object", "properties": {"error": {"type": "object", "properties": {"message": {"type": "string"}}, "required": ["message"]}}, "required": ["error"]}
  },
  "responses": {
   "MalaPeticion": {"description": "Peticion invalida", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
   "NoAuth": {"description": "Falta la llave bk_ o es invalida", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
   "Cuota": {"description": "Cuota agotada (dia o minuto)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}
  }
 },
 "paths": {
  "/status": {
   "get": {
    "summary": "Estado publico del servicio (sin llave)",
    "security": [],
    "responses": {
     "200": {"description": "Servicio vivo", "content": {"application/json": {"schema": {"type": "object", "properties": {"servicio": {"type": "string"}, "estado": {"type": "string"}, "version": {"type": "string"}, "hora": {"type": "string", "format": "date-time"}, "api": {"type": "array", "items": {"type": "string"}}}}}}}
    }
   }
  },
  "/v1/health": {
   "get": {
    "summary": "Healthcheck simple (sin llave)",
    "security": [],
    "responses": {
     "200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object", "properties": {"estado": {"type": "string"}}}}}}
    }
   }
  },
  "/v1/me": {
   "get": {
    "summary": "Cuota restante de tu llave",
    "responses": {
     "200": {"description": "Cuota del dia", "content": {"application/json": {"schema": {"type": "object", "properties": {"restantes_hoy": {"type": "integer"}, "limite_diario": {"type": "integer"}, "limite_por_minuto": {"type": "integer"}}, "required": ["restantes_hoy", "limite_diario"]}}}},
     "401": {"$ref": "#/components/responses/NoAuth"}
    }
   }
  },
  "/v1/chat": {
   "post": {
    "summary": "Conversa con Beatrice (agente con herramientas y revisor)",
    "description": "Un mensaje = una peticion de cuota. Usa herramientas (fecha, calculadora exacta, busqueda web, leer paginas) y un segundo modelo revisa lo dificil. max_tokens entre 50 y 2000 (800 por defecto).",
    "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mensaje": {"type": "string", "minLength": 1, "maxLength": 4000, "description": "Tu pregunta (alias: message)"}, "max_tokens": {"type": "integer", "minimum": 50, "maximum": 2000, "default": 800}, "modo": {"type": "string", "enum": ["auto", "profundo", "rapido"], "default": "auto"}, "dispositivo": {"type": "string", "description": "Contexto de tu equipo (opt-in de memoria)"}, "programa": {"type": "string", "description": "Programa que tenias abierto (opt-in)"}, "message": {"type": "string", "description": "Alias de mensaje"}}, "required": ["mensaje"]}}}},
    "responses": {
     "200": {"description": "Respuesta del agente", "headers": {"x-ratelimit-remaining-day": {"schema": {"type": "string"}}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"respuesta": {"type": "string"}, "modo": {"type": "string"}, "herramientas": {"type": "array", "items": {"type": "string"}}, "verificada": {"type": "boolean"}, "corregida_por_revisor": {"type": "boolean"}, "contexto_maquina": {"type": "boolean"}, "id": {"type": "string"}, "restantes_hoy": {"type": "integer"}}, "required": ["respuesta", "id"]}}}},
     "400": {"$ref": "#/components/responses/MalaPeticion"},
     "401": {"$ref": "#/components/responses/NoAuth"},
     "429": {"$ref": "#/components/responses/Cuota"}
    }
   }
  },
  "/v1/chat/completions": {
   "post": {
    "summary": "Endpoint compatible con clientes de OpenAI",
    "description": "Mismo agente, cuota y BYOK que /v1/chat. Cambia la URL base a https://beatrice-ia.pages.dev/v1 y tu llave bk_ y cualquier cliente de OpenAI funciona. Streaming NO soportado (stream debe ser false). usage reporta tokens estimados (caracteres/4).",
    "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"messages": {"type": "array", "minItems": 1, "maxItems": 40, "items": {"type": "object", "properties": {"role": {"type": "string"}, "content": {"type": "string"}}, "required": ["content"]}, "description": "Se concatenan los content y los resuelve el mismo agente"}, "model": {"type": "string", "default": "beatrice"}, "max_tokens": {"type": "integer", "minimum": 50, "maximum": 2000, "default": 800}, "max_completion_tokens": {"type": "integer", "minimum": 50, "maximum": 2000, "description": "Alias de max_tokens"}, "modo": {"type": "string", "enum": ["auto", "profundo", "rapido"], "default": "auto"}, "stream": {"type": "boolean", "enum": [false], "description": "Solo false: streaming aun no soportado"}}, "required": ["messages"]}}}},
    "responses": {
     "200": {"description": "Respuesta en formato chat.completion", "content": {"application/json": {"schema": {"type": "object", "properties": {"id": {"type": "string"}, "object": {"type": "string", "const": "chat.completion"}, "created": {"type": "integer"}, "model": {"type": "string"}, "choices": {"type": "array", "items": {"type": "object", "properties": {"index": {"type": "integer"}, "message": {"type": "object", "properties": {"role": {"type": "string"}, "content": {"type": "string"}}}, "finish_reason": {"type": "string"}}}}, "usage": {"type": "object", "properties": {"prompt_tokens": {"type": "integer"}, "completion_tokens": {"type": "integer"}, "total_tokens": {"type": "integer"}}}, "beatrice": {"type": "object", "properties": {"restantes_hoy": {"type": "integer"}, "verificada": {"type": "boolean"}}}}, "required": ["id", "object", "choices"]}}}},
     "400": {"$ref": "#/components/responses/MalaPeticion"},
     "401": {"$ref": "#/components/responses/NoAuth"},
     "429": {"$ref": "#/components/responses/Cuota"}
    }
   }
  },
  "/v1/classify": {
   "post": {
    "summary": "Procesa hasta 20 textos con tus instrucciones",
    "description": "Clasificar, extraer o etiquetar en lote. Responde EXCLUSIVAMENTE un JSON valido, una entrada por elemento, misma cantidad y orden.",
    "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"instrucciones": {"type": "string", "minLength": 1, "maxLength": 12000}, "items": {"type": "array", "minItems": 1, "maxItems": 20, "items": {"type": "string"}}, "max_tokens": {"type": "integer", "minimum": 300, "maximum": 4000, "default": 2000}}, "required": ["instrucciones", "items"]}}}},
    "responses": {
     "200": {"description": "Respuesta del lote", "content": {"application/json": {"schema": {"type": "object", "properties": {"respuesta": {"type": "string"}, "items": {"type": "integer", "description": "Cantidad de items recibidos"}, "id": {"type": "string"}, "restantes_hoy": {"type": "integer"}}, "required": ["respuesta", "id"]}}}},
     "400": {"$ref": "#/components/responses/MalaPeticion"},
     "401": {"$ref": "#/components/responses/NoAuth"},
     "429": {"$ref": "#/components/responses/Cuota"}
    }
   }
  }
 }
}
