API de Keural
Envíe solicitudes en formato OpenAI Chat Completions con una clave de API.
Llama a los modelos registrados en Keural con el formato OpenAI Chat Completions.
La URL base tiene el formato https://<su dominio público de API>/llm/v1. El dominio público de la API varía según el entorno; consulte con su administrador.
| Método | Ruta | Descripción |
|---|---|---|
POST | /llm/v1/chat/completions | Crea una finalización de chat (admite streaming) |
GET | /llm/v1/models | Lista los modelos conectados a la clave |
GET | /llm/v1/models/{model} | Obtiene información sobre un modelo conectado a la clave |
Las rutas de embeddings, generación de imágenes, voz y la API de Responses no se admiten, y devuelven 404.
Flujo de uso
| Paso | Qué hacer |
|---|---|
| 1. Emitir la clave | En Configuración → API, elija un modelo y obtenga una clave. Copie el ID del modelo y la clave. |
| 2. Conectar el cliente | Introduzca en la aplicación o el código la URL base, la clave de API y el ID del modelo. |
| 3. Usar y administrar | En la misma pantalla, consulte el uso y, si es necesario, vuelva a emitir o revoque la clave. |
Requisitos previos
| Elemento | Detalles |
|---|---|
| Cuenta de Keural | Cuenta con la que puede iniciar sesión. |
| Menú de API | Si no aparece API en Configuración, pida a su administrador que active la función. |
| Permiso de miembro de la organización | Para emitir claves en un espacio de trabajo de organización, el administrador de la organización debe permitírselo. Consulte Permiso de API de los miembros de la organización. |
| URL base | Dirección pública de la API indicada por el administrador. |
| Cliente | Aplicación o SDK compatible con las conexiones OpenAI API. |
Emitir una clave de API
- En el menú de cuenta, abra Configuración → API. En las aplicaciones de escritorio y móviles, está en el grupo Herramientas.
- En la pestaña API keys, elija el espacio de trabajo al que pertenece la clave (personal u organización) y el Model ID.
- Si lo necesita, establezca una New key expiration (optional, Korea time). Si lo deja vacío, la clave no caduca hasta que la revoque.
- Pulse Issue key, copie la clave con Copy key y guárdela en un lugar seguro. La clave completa solo se muestra en ese momento y no se puede volver a ver al cerrar la pantalla.
- La clave está vinculada al espacio de trabajo elegido y a un modelo. El uso se atribuye a la persona que emitió la clave.
- Cada combinación de espacio de trabajo y modelo solo puede tener una clave utilizable. Si ya existe una, no se emite otra nueva: vuelva a emitirla (Rotate) o revóquela (Revoke).
- Si pierde la clave, no hay forma de volver a verla. Vuelva a emitirla; al hacerlo, la clave anterior deja de funcionar de inmediato.
- Si aparece el mensaje de que no hay modelos disponibles, revise la configuración de visibilidad de los modelos, su plan y el permiso de API de la organización con su administrador.
Permiso de API de los miembros de la organización
Solo lo gestionan los propietarios y administradores de la organización. Para que un miembro pueda emitir claves en un espacio de trabajo de organización, el administrador debe permitírselo antes. Tanto los miembros nuevos como los existentes tienen el acceso bloqueado de forma predeterminada.
Gestión de la organización → Organization API tiene tres secciones. Si no aparece el menú, la función de API está desactivada o su cuenta no tiene permisos de administración de la organización.
| Sección | Qué hace |
|---|---|
| API permissions by user | Activa o desactiva el permiso de API de cada miembro. |
| Issued keys | Consulta el estado de las claves emitidas en la organización y las revoca. No puede ver el texto de las claves. |
| API usage | Consulta las solicitudes y el uso de tokens de las claves emitidas en la organización. |
| Acción | Resultado |
|---|---|
| Activar Allow API access | El miembro puede emitir claves en el espacio de trabajo de la organización. |
| Desactivar Allow API access | Se bloquean las nuevas emisiones y las llamadas con las claves existentes. Las claves ya emitidas no se eliminan automáticamente; si lo necesita, revóquelas en Issued keys. |
Cuando un miembro sale de la organización o es eliminado de ella, las claves que recibió en la organización se revocan automáticamente.
Conectar con un cliente
Introduzca estos tres valores en las aplicaciones compatibles con OpenAI API (clientes de chat, extensiones de IDE, herramientas de automatización, etc.).
| Valor | Qué introducir | Nombre en cada aplicación |
|---|---|---|
| Base URL | La dirección pública de la API que le indicó su administrador (…/llm/v1) | Base URL, API Base, Endpoint, Host |
| API Key | La clave emitida (sin espacios al principio ni al final) | API Key, Token, Secret Key, Authorization |
| Model | El Model ID de la pantalla de emisión. Debe coincidir exactamente con el modelo conectado a la clave | Model, Model ID, Model Name |
- En la configuración de la aplicación, añada una conexión compatible con OpenAI (Connection).
- Introduzca la Base URL y la API Key, y guarde.
- Elija un modelo en la lista de modelos. La lista muestra solo el modelo conectado a la clave.
- Envíe un mensaje corto para comprobar que recibe respuesta.
El formato de las solicitudes es el siguiente.
| Tipo | Contenido |
|---|---|
| Solicitud de chat | POST <Base URL>/chat/completions |
| Consulta de modelos | GET <Base URL>/models |
| Encabezado de autenticación | Authorization: Bearer <clave emitida> |
| Encabezado de contenido | Content-Type: application/json |
Primera solicitud
export KEURAL_API_KEY='su_clave_emitida'
export KEURAL_BASE_URL='https://<su-dominio-de-api>/llm/v1'
export MODEL_ID='ID_del_modelo_en_la_pantalla_de_emisión'
curl "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"Hola.\"}]}"El model del cuerpo de la solicitud debe coincidir con el modelo conectado a la clave. Si lleva un prefijo de ruta, como provider/ID_del_modelo, se compara lo que viene después de la última /. Si no coincide, la API devuelve 403. La respuesta siempre incluye en model el ID del modelo de la clave.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["KEURAL_API_KEY"],
base_url=os.environ["KEURAL_BASE_URL"],
)
res = client.chat.completions.create(
model=os.environ["MODEL_ID"],
messages=[{"role": "user", "content": "Hola."}],
)
print(res.choices[0].message.content)Campos de solicitud admitidos
La API solo acepta estos 18 campos de nivel superior. Si envía otros, devuelve 400. Los campos opcionales con valor null se tratan como no enviados.
| Campo | Regla |
|---|---|
model | Obligatorio. El ID del modelo de la clave |
messages | Obligatorio. De 1 a 4.096 elementos |
stream · stream_options | stream_options solo se envía con stream: true. Admite include_usage. |
tools | Hasta 128. El nombre de la función usa [A-Za-z0-9_-], de 1 a 64 caracteres |
tool_choice | none · auto · required · una función concreta. required requiere que haya tools. |
parallel_tool_calls | Si el modelo no lo admite, se devuelve 400 |
response_format | text · json_object · json_schema |
max_tokens · max_completion_tokens | Envíe solo uno de los dos. Si no se envía, el valor es 4.096 (o el límite del modelo si es menor). Si supera el límite del modelo, se devuelve 400. |
temperature | De 0 a 2. Si el modelo no lo admite, se devuelve 400 |
top_p | De 0 a 1 |
frequency_penalty · presence_penalty | De -2 a 2 |
stop | Una cadena o una matriz de hasta 4 elementos |
seed | Entero |
user | Hasta 256 caracteres |
n | Solo 1 |
Mensajes
| Rol | Campos admitidos |
|---|---|
system · developer | content, name |
user | content (cadena o matriz de partes de texto e imagen), name |
assistant | content, name, refusal, tool_calls |
tool | content, tool_call_id |
- Un mensaje
toolresponde una sola vez a cadaidde lostool_callsanteriores. - Las partes de imagen (
image_url) solo se incluyen en los mensajesuserde modelos que admiten imágenes. Use una direcciónhttpohttps, o un data URI base64 de PNG, JPEG, GIF o WebP.detailpuede serauto,lowohigh.
Cuerpo
| Elemento | Límite |
|---|---|
| Content-Type | application/json |
| Tamaño | 1 MiB |
| Estructura JSON | Un único objeto de nivel superior, profundidad de anidamiento de 64 como máximo, sin claves duplicadas |
| Tiempo de solicitud | Máximo 600 segundos |
Si incumple las reglas del cuerpo, se devuelve 400 con param igual a body.
Streaming
Si incluye "stream": true en la solicitud, la respuesta llega por SSE. Cada fragmento se envía como un evento data: ..., y al final se envía data: [DONE]. Si incluye "stream_options": {"include_usage": true}, se envía un fragmento adicional con el uso de tokens justo antes de [DONE].
Con include_usage, todos los fragmentos contienen usage: null, y el último fragmento de uso tiene choices como matriz vacía. Las respuestas sin streaming solo incluyen usage cuando se han confirmado los tokens de entrada y de salida.
El id de la respuesta tiene el formato chatcmpl-<x-request-id>. Todas las respuestas incluyen el encabezado x-request-id.
Si se produce un error durante el streaming, se envía un evento data: con el JSON del error y la conexión se cierra sin [DONE]. Si un fragmento supera 1 MiB o la respuesta supera 16 MiB, la conexión termina con 503.
curl -N "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"Hola.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true}}"Límites de uso
Las solicitudes tienen límites por usuario, organización y modelo: número de solicitudes simultáneas, solicitudes por minuto (RPM) y tokens por minuto (TPM). Los valores reales varían según el entorno.
Los tokens por minuto se descuentan al recibir la solicitud. La entrada se cuenta como 1 token por cada 4 caracteres en inglés, y el resto de caracteres como 1 token por carácter; cada imagen cuenta como 2.000 tokens. La salida se descuenta según max_tokens (máximo 4.096), así que si limita la salida a lo necesario, tendrá más margen dentro del límite.
Código 429 | Causa | Retry-After |
|---|---|---|
rate_limit_exceeded | Se superó el RPM, el TPM o el número de solicitudes simultáneas | 60 segundos para RPM y TPM; 1 segundo para las simultáneas |
api_busy | Se superó la capacidad de procesamiento del servidor | No hay. Espere un momento y vuelva a intentarlo. |
upstream_rate_limit | El proveedor del modelo superó su límite | No hay |
Gestión de claves
En la pestaña API keys de Configuración → API puede consultar el estado de las claves emitidas (válida, caducada o revocada), volver a emitirlas o revocarlas.
Las claves son cadenas de 51 caracteres que empiezan por krl_llm_. Cada cuenta de emisión solo puede tener una clave; si ya existe una, se vuelve a emitir. La fecha de caducidad solo puede fijarse a partir de hoy.
| Acción | Resultado | Qué tener en cuenta |
|---|---|---|
| Volver a emitir (Rotate) | Se obtiene una clave nueva. | La clave anterior deja de funcionar de inmediato. Cambie también la clave en las aplicaciones conectadas. |
| Revocar (Revoke) | La clave se bloquea de inmediato. | Úselo cuando sospeche que la clave se ha filtrado. Una clave revocada no se puede recuperar. |
Consulta de uso
Puede consultar las solicitudes de API y el consumo de tokens en los dos lugares siguientes.
| Ubicación | Contenido |
|---|---|
| Configuración → API → API usage | Uso de las claves que emitió en el espacio de trabajo actual |
| Gestión de la organización → Organization API, sección API usage | Uso de todas las claves emitidas en la organización (propietarios y administradores de la organización) |
Condiciones de consulta
| Condición | Descripción |
|---|---|
| Hora de inicio · Hora de fin | Hora de Corea. La hora de inicio se incluye y la de fin no. Si los deja vacíos, se muestran los últimos 7 días; puede consultar hasta 90 días como máximo. |
| Model ID | Muestra solo las solicitudes de un modelo concreto. Si lo deja vacío, se muestran todos. |
| Estado de la solicitud | Elija entre Todas · En curso · Completada · Con error · Interrumpida · Pendiente de confirmación. |
Defina las condiciones y pulse Consultar. Para incluir una solicitud que acaba de enviar, pulse Actualizar.
Valores que aparecen en pantalla
- Período de consulta aplicado: el período que se consultó realmente. Si dejó vacías la hora de inicio o de fin, o superó los 90 días, aparece el período que ajustó el servidor.
- Número de solicitudes y totales de tokens de entrada · tokens de salida · tokens totales: solo suman los valores confirmados. Los tokens que aún no se han confirmado aparecen como Sin confirmar.
- Lista de solicitudes: cada solicitud ocupa una fila con la hora, el Model ID, el estado y los tokens de entrada, salida y totales. Se muestran 20 por página; use Anterior y Siguiente para navegar.
Al pulsar Detalles de la solicitud de una fila, se despliegan los siguientes valores.
| Elemento | Descripción |
|---|---|
| ID de la solicitud | Valor que debe indicar al contactar con soporte. |
| Modo de respuesta | Streaming o respuesta normal |
| Estado de confirmación del uso | Confirmado · Parcialmente confirmado · Sin confirmar |
| Hora de finalización · Tiempo de respuesta (ms) | Momento en que terminó la solicitud y tiempo que tardó |
| Lectura de caché · Creación de caché · Tokens de razonamiento | Solo se muestran si el modelo devuelve estos valores. |
Las solicitudes en streaming registran el uso aunque no incluya stream_options.include_usage. Si una solicitud se interrumpe a mitad, puede quedar como Parcialmente confirmado o Sin confirmar.
Formato de error
Los errores se devuelven en formato compatible con OpenAI.
{
"error": {
"message": "Descripción del error legible para las personas",
"type": "authentication_error",
"code": "invalid_api_key",
"param": null
}
}type depende del código de estado, y code indica la causa concreta.
| Estado | type | code | Causa |
|---|---|---|---|
400 | invalid_request_error | invalid_request | Incumplimiento de un campo, un valor o una regla del cuerpo. param indica el campo afectado |
400 | invalid_request_error | upstream_rejected_request | El proveedor del modelo rechazó la solicitud |
401 | authentication_error | invalid_api_key | Formato de clave incorrecto, clave ausente, caducada, revocada o vuelta a emitir, o más de un encabezado Authorization |
403 | permission_error | api_disabled | La función de API de Keural está desactivada |
403 | permission_error | model_api_disabled | La publicación del modelo para la API está desactivada |
403 | permission_error | model_not_allowed | model no coincide con el modelo de la clave, o el miembro no tiene permiso de API |
404 | invalid_request_error | not_found | Ruta inexistente |
405 | invalid_request_error | method_not_allowed | Método incorrecto. El encabezado Allow indica los métodos permitidos |
429 | rate_limit_error | Tabla de Límites de uso | Límite superado |
503 | server_error | upstream_timeout | No se completó la respuesta en 600 segundos |
503 | server_error | invalid_upstream_response | Formato de respuesta anómalo del proveedor, o tamaño de flujo superado |
503 | server_error | dependency_unavailable · unsupported_provider | Problema interno temporal. Contacte con soporte e incluya x-request-id |
Solución de problemas
| Síntoma | Código de respuesta | Qué revisar primero |
|---|---|---|
| La lista de modelos está vacía o no se puede conectar | 404 · 405 | Que la Base URL termine en …/llm/v1 |
| Falla la autenticación | 401 | Errores tipográficos o espacios en la clave; si está caducada, revocada o vuelta a emitir |
| Se conecta, pero no se puede usar el modelo | 403 | Que el ID del modelo coincida con el de la clave y el permiso de API de la organización |
| La respuesta tarda o falla de vez en cuando | 429 | Límites de uso |
| Temporalmente no llega respuesta | 5xx | Vuelva a intentarlo más tarde |
| El uso no aparece o no coincide con el real | — | El período de consulta y el espacio de trabajo al que pertenece la clave |
Si el problema persiste, contacte con su administrador e incluya la siguiente información. No envíe el texto de la clave ni el contenido de los prompts.
- Hora de la incidencia
- ID del modelo usado
- Nombre y versión de la aplicación cliente
- Valor de
x-request-iddel encabezado de respuesta - Mensaje de error que aparece en pantalla