Referencia de la API de Jenova Agent
URL base: https://api.jenova.ai/v1
Autenticación: Token Bearer en el encabezado Authorization
Tabla de contenido
- Descripción general
- Guía de inicio rápido
- Conceptos básicos
- Autenticación
- Puntos de conexión de la API
- Transmisión (SSE)
- Integración con servidor MCP
- Facturación
- Límites de solicitudes
- Manejo de errores
- Paginación
- Localización
- Privacidad y datos
- Soporte
Descripción general
Cree y ejecute Agentes de IA listos para producción sin tener que ensamblar usted mismo la infraestructura subyacente. La API de Jenova Agent reúne todas las capacidades principales en un único servicio administrado:
La pila completa de Agentes
- Orquestación de Agentes: Una capa de orquestación unificada coordina Modelos, Herramientas, memoria y recuperación en flujos de trabajo complejos.
- Memoria y contexto: Memoria de conversación y contexto ilimitados integrados en cada Sesión. No se requiere administración de estado externo.
- Herramientas y MCP: Integraciones ilimitadas de Herramientas con Herramientas nativas de la plataforma y cualquier servidor MCP remoto, listas para usar desde el primer momento.
- Use cualquier Modelo: Potencie sus Agentes con Modelos de OpenAI, Anthropic, Google, xAI, Qwen y más a través de una única integración.
- Almacenamiento totalmente administrado: Bases de datos relacionales y vectoriales administradas con RAG integrado. Sin infraestructura que aprovisionar ni escalar.
- Nivel de producción: Utilizado por cientos de miles de usuarios. Infraestructura totalmente administrada, APIs estables, diseñado para tráfico de producción.
Guía de inicio rápido
1. Obtenga su clave de API
Genere una Clave de API desde el Panel de control para desarrolladores en www.jenova.ai/platform. Las claves utilizan el formato jnv_sk_* y se envían como tokens Bearer.
2. Elija o cree un Agente
Elija un Agente prediseñado de la plataforma, o cree un Agente personalizado en el Panel de control con instrucciones, configuración de Modelo, archivos de Base de conocimientos, Herramientas y servidores MCP.
3. Envíe su primer Mensaje
Cree una Sesión y envíe un Mensaje en una sola llamada:
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "What can you help me with?"
}'
La respuesta se transmite de vuelta como Server-Sent Events:
event: stream_started
data: {"session_id":"ses_xyz789","run_id":"run_abc123","agent":"my-support-agent"}
event: stream_delta
data: {"session_id":"ses_xyz789","run_id":"run_abc123","chunk_content":"I can help you with ","seq":1}
event: stream_ended
data: {"session_id":"ses_xyz789","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}
Capture session_id de stream_started para solicitudes posteriores. Para respuestas JSON síncronas, consulte Enviar Mensaje.
Conceptos básicos
Agente
Un Agente de IA con el que usted interactúa a través de la API. Cada Agente tiene un slug único (por ejemplo, my-support-agent) que se utiliza como el valor agent en las llamadas a la API.
- Prediseñado: Seleccione entre los Agentes existentes en la plataforma.
- Personalizado: Configure el suyo propio en el Panel de control con instrucciones, Modelo, Base de conocimientos, Herramientas y servidores MCP.
Sesión
Un hilo de conversación independiente entre un Usuario final y un Agente.
- Identificador: ID con prefijo (por ejemplo,
ses_abc123) - Alcance: Pueden existir varias Sesiones para el mismo Agente y Usuario final, cada una con un estado de conversación independiente
- Ciclo de vida: Las Sesiones persisten indefinidamente hasta que se eliminan mediante la API. Para tareas puntuales sin almacenamiento, use
POST /messagesconephemeral: true - Aislamiento de plataforma: Las Sesiones de la API son independientes de las conversaciones en la aplicación web de Jenova. Los Usuarios finales, el historial de Sesiones y la Facturación son independientes entre la API y la aplicación web.
Mensaje
Una entrada individual en el historial de conversación de una Sesión, devuelta por los puntos de conexión de Mensajes. Cada Mensaje incluye un objeto from estructurado con type ("user" o "agent") y name, además de un type de Mensaje:
external- un Mensaje de conversación destinado a mostrarse como contenido de chat.internal- un Mensaje opcional que representa los pasos de trabajo del Agente durante una Ejecución, como llamadas a Herramientas o recuperación.
Ejecución
Una única ejecución de Agente creada al enviar un Mensaje. Una Ejecución tiene un run_id, puede transmitir Eventos mientras está activa y produce uno o más Mensajes completados. Cada Sesión solo puede tener una Ejecución activa a la vez.
Usuario final
El campo user asocia las Sesiones a un Usuario final dentro de su aplicación. Use un ID opaco y estable, como su ID de usuario interno o un UUID. Evite correos electrónicos u otra información de identificación personal, a menos que su aplicación lo requiera. Las Sesiones creadas con el mismo valor de user se agrupan entre sí, lo que permite listar Sesiones por usuario.
Si se omite user, la Sesión queda asociada a su cuenta de desarrollador y no podrá filtrarse posteriormente por Usuario final. Envíe user en producción.
En las solicitudes sobre Sesiones existentes, user funciona como una verificación opcional de propiedad. Si lo proporciona, debe coincidir con el valor de user utilizado al crear la Sesión; de lo contrario, la API devuelve 404 session_not_owned. Envíelo como Parámetro de consulta en las solicitudes GET y DELETE, y en el cuerpo JSON en las solicitudes POST y PATCH.
Autenticación
Autentique cada solicitud con un token Bearer en el encabezado Authorization:
Authorization: Bearer jnv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Las claves de API se generan desde el panel de control para desarrolladores.
User-Agent es opcional. Los SDKs pueden configurarlo con fines de diagnóstico, pero la API no lo requiere.
Formato de clave: Las claves comienzan con el prefijo jnv_sk_ seguido de una cadena aleatoria codificada en base62.
Límites: Cada cuenta de desarrollador puede tener hasta 10 claves de API activas.
Puntos de conexión de la API
Mensajes
El envío de Mensajes es la ruta principal de la API. Use POST /messages para el primer Mensaje; este crea la Sesión e inicia la Ejecución en una sola solicitud. Use POST /sessions/{session_id}/messages al continuar una Sesión capturada mediante su session_id.
Enviar Mensaje
POST /messages
Crea una Sesión persistente y envía el primer Mensaje en una única solicitud atómica. Establezca ephemeral: true para una solicitud de una sola vez con Transmisión y sin almacenamiento, que no guarda historial de Sesión ni de Mensajes, no devuelve un ID de Sesión y no se puede continuar.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Valor predeterminado | Descripción |
|---|---|---|---|---|
agent | string | Sí | - | El identificador slug del Agente |
content | string | Condicional | - | Texto del Mensaje. Obligatorio a menos que se proporcione file_urls |
file_urls | string[] | Condicional | - | URLs de los archivos a adjuntar. Obligatorio a menos que se proporcione content |
user | string | No | - | Su identificador externo de Usuario final (máximo 255 caracteres). Si se omite, se usa de forma predeterminada su cuenta de desarrollador |
session_name | string | No | - | Nombre visible para la nueva Sesión (máximo 200 caracteres) |
ephemeral | boolean | No | false | Solicitud de una sola vez, sin almacenamiento y solo con Transmisión. No guarda historial de Sesión ni de Mensajes, no devuelve un ID de Sesión y no se puede continuar |
stream | boolean | No | true | true para Transmisión mediante SSE, false para JSON. La autorización de MCP requiere Transmisión |
model | string | No | - | Sustitución puntual del Modelo solo para esta solicitud. Use un ID de Modelo estable como claude-sonnet-5. No cambia el Modelo predeterminado de la Sesión |
Ejemplo - Transmisión (predeterminado)
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account"
}'
La respuesta es un flujo SSE (consulte Transmisión (SSE) para conocer el formato de los Eventos). Las solicitudes persistentes incluyen el nuevo session_id; las solicitudes con ephemeral: true omiten session_id y deben usar Transmisión.
Ejemplo - JSON (sin Transmisión)
curl -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account",
"stream": false
}'
Respuesta
Las respuestas con Transmisión emiten los Eventos SSE documentados en Transmisión (SSE). Las respuestas sin Transmisión devuelven la estructura JSON de Mensaje mostrada en Continuar Sesión, incluidos stop_reason y usage para la solicitud completada.
Si una Ejecución sin Transmisión sigue procesándose después de 90 segundos, la API devuelve 202 Accepted con status: "processing", session_id, run_id y message. La Ejecución continúa después de la respuesta o de la desconexión del cliente; verifique los Mensajes de la Sesión, o use Transmisión para flujos de trabajo más largos.
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | missing_required_field | agent es obligatorio |
| 400 | invalid_payload | JSON con formato incorrecto, o un campo tiene un tipo no válido |
| 400 | bad_request | Modo ephemeral no válido, o user/session_name supera su longitud máxima |
| 400 | content_or_uploaded_files_required | No se proporcionó ni content ni file_urls |
| 400 | content_too_long | El contenido del Mensaje supera la longitud máxima de tokens |
| 400 | exceed_max_upload_files | Más de 10 URLs de archivo en una sola solicitud |
| 400 | unsupported_file_format | Una URL de archivo tiene una extensión de archivo no admitida |
| 400 | invalid_file_url | Una URL de archivo tiene un formato incorrecto o no usa HTTPS |
| 400 | invalid_model_selection | La sustitución de Modelo no corresponde a un Modelo de producción válido |
| 402 | insufficient_credits | Créditos insuficientes para crear la Sesión o enviar el Mensaje |
| 404 | agent_not_found | El Agente no existe o no es accesible para su cuenta |
Continuar Sesión
POST /sessions/{session_id}/messages
Envía un Mensaje a una Sesión persistente existente y recibe la respuesta del agente. Las respuestas se transmiten mediante SSE de forma predeterminada; establezca stream: false para JSON.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Valor predeterminado | Descripción |
|---|---|---|---|---|
content | string | Condicional | - | Texto del Mensaje. Obligatorio a menos que se proporcione file_urls |
file_urls | string[] | Condicional | - | URLs de los archivos que se adjuntarán. Obligatorio a menos que se proporcione content |
stream | boolean | No | true | true para Transmisión mediante SSE, false para JSON. La autorización de MCP requiere Transmisión |
model | string | No | - | Anulación puntual del Modelo solo para esta solicitud. Use un ID de Modelo estable, como claude-sonnet-5. No cambia el Modelo predeterminado de la Sesión |
Ejemplo - Transmisión (predeterminado)
curl -N -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "How do I reset my password?"
}'
Ejemplo - JSON (sin Transmisión)
curl -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "How do I reset my password?",
"stream": false
}'
Respuesta 200 OK
{
"id": "msg_xyz789",
"session_id": "ses_abc123",
"sequence": 4,
"from": {
"type": "agent",
"name": "my-support-agent"
},
"type": "external",
"time": "2026-05-19T10:31:05Z",
"content": "To reset your password, go to Settings > Security > Change Password...",
"model": "claude-sonnet-5",
"files": [],
"stop_reason": "end_run",
"usage": {
"cost": "0.0015"
}
}
Si la Sesión ya tiene una Ejecución activa o Mensajes en cola, la API devuelve JSON 202 Accepted con status: "queued", session_id, run_id y message_id. El Mensaje del usuario es procesado por la Ejecución activa.
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | invalid_payload | JSON con formato incorrecto o un campo tiene un tipo no válido |
| 400 | content_or_uploaded_files_required | No se proporcionó ni content ni file_urls |
| 400 | content_too_long | El contenido del Mensaje supera la longitud máxima de tokens |
| 400 | exceed_max_upload_files | Más de 10 URLs de archivos en una sola solicitud |
| 400 | unsupported_file_format | Una URL de archivo tiene una extensión de archivo no admitida |
| 400 | invalid_file_url | Una URL de archivo tiene un formato incorrecto o no usa HTTPS |
| 400 | invalid_model_selection | La anulación de Modelo no corresponde a un Modelo de producción válido |
| 402 | insufficient_credits | Créditos insuficientes para enviar un Mensaje |
| 404 | session_not_found | La Sesión no existe |
| 404 | session_not_owned | La Sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
Idempotencia
POST /messages y POST /sessions/{session_id}/messages aceptan un Encabezado opcional Idempotency-Key. Utilice una clave única para cada envío lógico de usuario para que los reintentos de red o los envíos duplicados no generen Ejecuciones duplicadas.
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: send-user_12345-2026-05-19T10:30:00Z" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello"
}'
Sin transmisión: Reintentar devuelve la Respuesta 200 o 202 guardada con el Encabezado Idempotent-Replayed: true.
Transmisión: El flujo no se reproduce nuevamente. Reintentar mientras se está ejecutando o después de completarse devuelve un error de idempotencia con el run_id original y, para solicitudes persistentes, session_id. Utilice GET /sessions/{session_id}/runs/{run_id} para verificar una Ejecución activa, o GET /sessions/{session_id}/messages para obtener los resultados persistidos.
Ejemplo de reintento de transmisión completada:
HTTP/1.1 409 Conflict
Content-Type: application/json
{
"error": {
"code": "idempotency_key_reused",
"message": "This Idempotency-Key has already completed. Streaming responses cannot be replayed; use the returned session_id and run_id to retrieve the result."
},
"idempotency": {
"status": "completed",
"session_id": "ses_abc123",
"run_id": "run_abc123"
}
}
Errores de idempotencia
| Estado | Código | Condición |
|---|---|---|
| 409 | idempotency_key_reused | La misma clave se utilizó con una solicitud diferente |
| 409 | idempotency_key_in_use | La solicitud original todavía se está ejecutando |
| 409 | idempotency_key_reused | La solicitud de transmisión original ya se completó y no se puede reproducir nuevamente |
Listar Mensajes
GET /sessions/{session_id}/messages
Devuelve una lista paginada de mensajes de conversación visibles. La primera página contiene los mensajes más recientes; dentro de cada página, los mensajes están en orden cronológico (los más antiguos primero). sequence es un número de orden estable dentro de la sesión.
Parámetros de consulta
| Parámetro | Tipo | Valor predeterminado | Máx | Descripción |
|---|---|---|---|---|
limit | integer | 20 | 100 | Mensajes por página |
cursor | string | - | - | Cursor de paginación |
Ejemplo
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=50" \
-H "Authorization: Bearer jnv_sk_xxx"
Respuesta 200 OK
{
"items": [
{
"id": "msg_002",
"session_id": "ses_abc123",
"sequence": 4,
"from": {
"type": "agent",
"name": "my-support-agent"
},
"type": "external",
"time": "2026-05-19T10:31:05Z",
"content": "To reset your password, go to Settings > Security...",
"model": "claude-sonnet-5",
"files": []
}
],
"next_cursor": "",
"has_more": false
}
Objeto de Mensaje
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID del mensaje (con el prefijo msg_) |
session_id | string | ID de la sesión principal |
sequence | integer | Número de orden estable dentro de la sesión |
from | object | Objeto del remitente con type ("user" o "agent") y name |
type | string | Tipo de mensaje, normalmente external para mensajes de conversación visibles |
time | string | Marca de tiempo en formato ISO 8601 |
content | string | Contenido de texto. Presente en mensajes externos |
model | string | ID estable del modelo que generó la respuesta. Solo está presente en mensajes del agente |
files | array | Archivos adjuntos o generados incluidos con el mensaje. Cada entrada incluye file_id, name, url, format y size cuando se conoce |
stop_reason | string | Presente en mensajes de agente completados. El valor actual es end_run |
agent | string | Slug del agente en ejecución, cuando está disponible |
agent_name | string | Nombre visible del agente en ejecución, cuando está disponible |
Objeto de archivo
| Campo | Tipo | Descripción |
|---|---|---|
file_id | string | ID de archivo de Jenova, cuando está disponible |
name | string | Nombre del archivo |
url | string | URL del archivo, cuando está disponible |
format | string | Formato de archivo en minúsculas, como pdf, png o csv |
size | integer | Tamaño del archivo en bytes, cuando se conoce |
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | bad_request | Parámetro de consulta no válido |
| 404 | session_not_found | La sesión no existe |
| 404 | session_not_owned | La sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
Obtener Mensaje
GET /sessions/{session_id}/messages/{message_id}
Recupera un único mensaje visible por ID.
Respuesta 200 OK
Devuelve un único objeto de mensaje con la misma estructura que la respuesta de la lista.
Errores
| Estado | Código | Condición |
|---|---|---|
| 404 | session_not_found | La sesión no existe |
| 404 | session_not_owned | La sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
| 404 | not_found | El mensaje no existe en esta sesión |
Archivos adjuntos
Proporcione URLs HTTPS públicamente accesibles en el campo file_urls.
| Límite | Valor |
|---|---|
| Máximo de archivos por mensaje | 10 |
| Tamaño máximo de archivo | 20 MB por archivo |
Formatos admitidos
- Imágenes: JPG, JPEG, PNG, WebP
- Documentos: PDF, DOCX, XLSX, PPTX, TXT, CSV, RTF, MD, HTML, XML, JSON, LOG
- Código: JS, TS, TSX, JSX, PY, Java, Go, C, CPP, H, HPP, CS, RB, PHP, RS, Swift, KT, Scala, SQL, CSS, YAML, YML
Al listar mensajes, los archivos adjuntos aparecen en el arreglo files del mensaje.
Sesiones
Las sesiones son conversaciones persistentes entre un usuario final y un agente. La mayoría de las integraciones pueden crearlas de forma implícita con POST /messages.
Crear Sesión
POST /sessions
Crea una sesión persistente vacía vinculada a un agente específico. Utilice esto cuando necesite un ID de sesión antes del primer mensaje; de lo contrario, prefiera POST /messages.
Nota:
ephemeralno se acepta enPOST /sessions; usePOST /messagesconephemeral: truepara solicitudes puntuales sin almacenamiento.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
agent | string | Sí | El identificador slug del agente |
user | string | No | Su identificador externo de usuario final (máximo 255 caracteres). Si se omite, se utiliza de forma predeterminada su cuenta de desarrollador |
session_name | string | No | Nombre para mostrar de la sesión (máximo 200 caracteres) |
Ejemplo
curl -X POST https://api.jenova.ai/v1/sessions \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"session_name": "Billing inquiry"
}'
Respuesta 201 Created
{
"id": "ses_abc123",
"session_name": "Billing inquiry",
"agent": "my-support-agent",
"user": "user_12345",
"model": "claude-sonnet-5",
"created_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T10:30:00Z"
}
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | invalid_payload | JSON con formato incorrecto o un campo tiene un tipo inválido |
| 400 | missing_required_field | Se requiere agent |
| 400 | bad_request | Se proporcionó ephemeral, o user/session_name excede su longitud máxima |
| 402 | insufficient_credits | Créditos insuficientes para crear una sesión |
| 404 | agent_not_found | El agente no existe o no es accesible para su cuenta |
Listar Sesiones
GET /sessions
Devuelve una lista paginada de sus sesiones, ordenadas por la más recientemente actualizada.
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
limit | integer | Elementos por página (valor predeterminado 20, máximo 100) |
cursor | string | Cursor de paginación |
user | string | Filtrar por identificador de usuario final (máximo 255 caracteres) |
agent | string | Filtrar por slug del agente |
Ejemplo
curl "https://api.jenova.ai/v1/sessions?user=user_12345&limit=10" \
-H "Authorization: Bearer jnv_sk_xxx"
Respuesta 200 OK
{
"items": [
{
"id": "ses_abc123",
"session_name": "Billing inquiry",
"agent": "my-support-agent",
"user": "user_12345",
"model": "claude-sonnet-5",
"created_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T11:15:00Z"
}
],
"next_cursor": "eyJ2IjoxLCJrIjoiY3VyXzAxIn0",
"has_more": true
}
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | bad_request | Parámetro de consulta inválido |
Obtener Sesión
GET /sessions/{session_id}
Recupera una sola sesión por ID.
Respuesta 200 OK
Devuelve un objeto de sesión con la misma estructura que la respuesta de creación.
Errores
| Estado | Código | Condición |
|---|---|---|
| 404 | session_not_found | La sesión no existe |
| 404 | session_not_owned | La sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
Renombrar Sesión
PATCH /sessions/{session_id}
Actualiza el nombre visible de una sesión.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
session_name | string | Sí | Nuevo nombre visible (máximo 200 caracteres) |
Respuesta 200 OK
Devuelve el objeto de sesión actualizado.
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | invalid_payload | JSON malformado o un campo tiene un tipo no válido |
| 400 | missing_required_field | session_name es obligatorio |
| 400 | bad_request | session_name supera su longitud máxima |
| 404 | session_not_found | La sesión no existe |
| 404 | session_not_owned | La sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
Eliminar Sesión
DELETE /sessions/{session_id}
Elimina permanentemente una sesión y todos sus mensajes. La sesión no debe tener una ejecución activa.
Respuesta 204 No Content
Errores
| Estado | Código | Condición |
|---|---|---|
| 404 | session_not_found | La sesión no existe |
| 404 | session_not_owned | La sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
| 409 | busy | La sesión tiene una ejecución activa; cancélela primero |
Operaciones
Estos puntos de conexión son controles de recuperación y edición para sesiones persistentes. La mayoría de las integraciones solo necesitan Cancelar; use las demás operaciones cuando desee alterar o recuperar el estado de la sesión de forma intencionada. Todas las operaciones admiten la protección de propiedad opcional user descrita en Usuario final.
Cancelar Ejecución activa
POST /sessions/{session_id}/cancel
Cancela la ejecución del agente actualmente en curso. Esto no elimina los mensajes que ya se completaron antes de la cancelación.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
run_id | string | No | Protección opcional contra ejecuciones obsoletas. Si se proporciona y no coincide con la ejecución activa, la API devuelve 409 stale_run |
Respuesta 204 No Content
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | cancel_not_allowed | No hay ninguna ejecución activa para cancelar, o la cancelación no está permitida |
| 404 | session_not_found | La sesión no existe |
| 404 | session_not_owned | La sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
| 409 | stale_run | El run_id proporcionado no coincide con la ejecución activa |
Deshacer Ejecución activa
POST /sessions/{session_id}/undo
Cancela la ejecución activa, espera a que se detenga y luego elimina los mensajes que ya había agregado. No se conserva ninguna salida adicional después de emitir la operación de deshacer.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
run_id | string | No | Protección opcional contra ejecuciones obsoletas. Si se proporciona y no coincide con la ejecución activa, la API devuelve 409 stale_run |
Respuesta 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"deleted": ["msg_002", "msg_001"]
}
Si la ejecución se cancela antes de que se complete algún mensaje, deleted es un array vacío.
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | cancel_not_allowed | No hay ninguna ejecución activa para deshacer, o la cancelación no está permitida |
| 404 | session_not_found | La sesión no existe |
| 404 | session_not_owned | La sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
| 409 | stale_run | El run_id proporcionado no coincide con la ejecución activa |
| 409 | busy | La sesión no está disponible temporalmente porque hay otra actualización en curso |
Eliminar Mensajes recientes
POST /sessions/{session_id}/messages/delete
Elimina los N Mensajes más recientes de una Sesión inactiva. La Sesión no debe tener una Ejecución activa.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
count | integer | Sí | Número de Mensajes recientes a eliminar desde el final (debe ser mayor que 0) |
Respuesta 200 OK
{
"deleted": ["msg_002", "msg_001"]
}
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | bad_request | count falta, es cero o negativo; o no hay Mensajes para eliminar |
| 404 | session_not_found | La Sesión no existe |
| 404 | session_not_owned | La Sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
| 409 | busy | La Sesión tiene una Ejecución activa |
Bifurcar Sesión
POST /sessions/{session_id}/fork
Crea una nueva Sesión copiando la Sesión de origen hasta un Mensaje específico. La Sesión de origen no debe tener una Ejecución activa.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
message_id | string | No | ID del Mensaje del punto de bifurcación. Si se omite, la bifurcación se realiza desde el último Mensaje |
Respuesta 201 Created
Devuelve el objeto de Sesión recién creado con la misma estructura que la creación de una Sesión.
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | bad_request | message_id no es válido |
| 402 | insufficient_credits | No hay suficientes Créditos para bifurcar una Sesión |
| 404 | not_found | message_id no existe en esta Sesión |
| 404 | session_not_found | La Sesión no existe |
| 404 | session_not_owned | La Sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
| 409 | busy | La Sesión de origen tiene una Ejecución activa |
Obtener estado de Ejecución
GET /sessions/{session_id}/runs/{run_id}
Devuelve el estado actual de una Ejecución activa. Use esto después de una conexión SSE interrumpida o de una respuesta de idempotencia que devolvió un run_id. Una vez que finalice la Ejecución, obtenga los resultados con GET /sessions/{session_id}/messages.
Respuesta 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"status": "streaming",
"started_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T10:30:06Z",
"content": "Partial visible response text so far"
}
La respuesta también puede incluir indicios de progreso recientes mientras la Ejecución está activa.
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | bad_request | La Sesión es efímera |
| 404 | session_not_found | La Sesión no existe |
| 404 | session_not_owned | La Sesión pertenece a otro desarrollador o no coincide con el user proporcionado |
| 404 | not_found | La Ejecución no está activa para esta Sesión |
Créditos
Obtener saldo
GET /credits/balance
Devuelve su saldo actual de Créditos.
Respuesta 200 OK
{
"balance": "123.45"
}
Agentes
Cree y edite Agentes personalizados en el Panel de control. Próximamente se ofrecerá compatibilidad con la API para crear y editar Agentes.
Los flujos de trabajo programados o en segundo plano no son compatibles actualmente a través de la API. El Soporte para esta función estará disponible próximamente.
Listar Agentes
GET /agents
Devuelve los agentes disponibles para su clave de API. Utilice el valor agent al crear sesiones o enviar mensajes.
Respuesta 200 OK
{
"agents": [
{
"agent": "jenova",
"display_name": "Jenova",
"description": "General-purpose Jenova agent"
},
{
"agent": "my-support-agent",
"display_name": "Support Agent",
"description": "Answers customer questions"
}
]
}
| Campo | Tipo | Descripción |
|---|---|---|
agent | string | Slug estable del agente que se debe indicar como valor de agent |
display_name | string | Nombre visible legible por personas |
description | string | Descripción del agente |
Modelos
Listar Modelos
GET /models
Devuelve todos los modelos disponibles para usar en el campo model al enviar mensajes.
Respuesta 200 OK
{
"models": [
{
"id": "claude-opus-4-8",
"name": "Claude Opus 4.8",
"thinking_variant": "claude-opus-4-8-thinking"
},
{
"id": "claude-opus-4-8-thinking",
"name": "Claude Opus 4.8 (Thinking)"
},
{
"id": "kimi-k2.6",
"name": "Kimi K2.6",
"thinking_variant": "kimi-k2.6-thinking"
}
]
}
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Identificador estable del modelo. Se pasa como valor de model en Send Message |
name | string | Nombre visible legible por personas |
thinking_variant | string | ID del modelo de la variante de razonamiento/pensamiento. Presente solo en los modelos base que admiten razonamiento |
Los modelos con un thinking_variant admiten razonamiento extendido. Utilice el ID de la variante directamente en el campo model para habilitarlo.
Si no se especifica un model al enviar un mensaje, se utiliza el modelo predeterminado del agente.
Documentación
GET /docs?lang=en
GET /doc?lang=en
Devuelve esta referencia en formato Markdown. Utilice lang para seleccionar el idioma.
Transmisión (SSE)
Cuando se omite stream o se establece en true (valor predeterminado), las respuestas de los mensajes se entregan como Server-Sent Events. Utilice los eventos message_completed para identificar los mensajes listos para recuperar o renderizar.
Tiempo de espera: las conexiones SSE permanecen abiertas hasta 60 minutos. Las solicitudes sin transmisión esperan hasta 90 segundos y luego devuelven 202 Accepted mientras la ejecución continúa.
Encabezados de conexión
La respuesta SSE establece estos encabezados:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
X-Run-Id: run_abc123
X-Run-Id está disponible antes del primer evento SSE.
Reconexión y recuperación
Las transmisiones SSE no se reproducen. Si la conexión se interrumpe, utilice los valores capturados session_id y run_id para recuperar el estado:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/runs/run_abc123" \
-H "Authorization: Bearer jnv_sk_xxx"
Si la ejecución sigue activa, esto devuelve el estado actual, el texto parcial y el progreso reciente. Si devuelve 404 not_found, la ejecución ya no está activa; recupere los mensajes de la sesión para reconciliar la salida completada:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=20" \
-H "Authorization: Bearer jnv_sk_xxx"
Formato de trama
Cada trama SSE sigue el formato estándar:
event: <event_type>
data: <json_payload>
Dos saltos de línea terminan cada trama.
Tipos de Evento
Los flujos incluyen eventos de ciclo de vida, delta de texto, pensamiento, progreso, advertencia, finalización de mensaje, conexión MCP, error, final y ping. Algunos tipos de evento solo se envían cuando son relevantes.
En el caso de solicitudes efímeras (ephemeral: true), todos los eventos SSE omiten session_id. Utilice únicamente run_id para correlacionar los eventos dentro de esa única transmisión.
Para la reconciliación final en solicitudes persistentes, espere el Evento stream_ended y luego llame a List Messages.
Campos comunes en los eventos con ámbito de Ejecución:
| Campo | Descripción |
|---|---|
session_id | ID de la Sesión. Se omite en las transmisiones efímeras. Capture este valor de stream_started para solicitudes de seguimiento al usar POST /messages de forma persistente |
run_id | ID de la Ejecución actual, cuando esté disponible |
stream_started
Se envía una vez cuando comienza la Ejecución.
| Campo | Descripción |
|---|---|
agent | Slug del Agente de la Sesión, cuando esté disponible |
stream_delta
Se envía repetidamente mientras el Agente genera texto de respuesta visible. Concatene los valores de chunk_content en el orden de seq para construir la respuesta transmitida.
event: stream_delta
data: {"session_id":"ses_abc123","run_id":"run_abc123","chunk_content":"To reset your ","seq":1}
| Campo | Descripción |
|---|---|
chunk_content | Fragmento de texto |
seq | Secuencia monótona de fragmentos dentro de la transmisión |
stream_thinking
Se envía repetidamente mientras el Agente emite salida de pensamiento. Utilícelo para un indicador de pensamiento independiente o una vista de trazas; no lo concatene en el texto final de la respuesta.
| Campo | Descripción |
|---|---|
content | Fragmento de texto de pensamiento |
stream_progress
Informa de actividad visible para el usuario durante la generación, como leer un documento, buscar en la web o esperar una acción del usuario. Estos eventos están destinados a una visualización temporal en la interfaz; ignore los campos desconocidos. Use los mensajes completados como historial de mensajes autoritativo.
Avanzado: las solicitudes de Mensaje aceptan include_progress: false para omitir únicamente stream_progress. Los eventos de ciclo de vida, ping, message_completed, los errores y los eventos terminales se siguen enviando cuando corresponde.
| Campo | Descripción |
|---|---|
state | Estado del ciclo de vida: running, in-progress, success, failed, skipped, complete, cancelled, entre otros. Gestione con tolerancia los valores desconocidos |
label | Etiqueta de actividad legible por humanos |
Algunos eventos de progreso pueden incluir url, file_name o server_name como indicaciones opcionales de visualización.
message_completed
Se envía cada vez que un Mensaje está completo y listo para ser recuperado o representado.
Este es un marcador de límite, no el objeto de Mensaje completo. Recupere el Mensaje si necesita su contenido o metadatos.
event: message_completed
data: {"session_id":"ses_abc123","run_id":"run_abc123","message_id":"msg_abc123","sequence":4,"from":{"type":"agent","name":"Jenova"},"type":"external"}
| Campo | Descripción |
|---|---|
message_id | ID del Mensaje completado |
sequence | Número de orden estable dentro de la Sesión |
from | Objeto del remitente con type (user o agent) y name |
type | Tipo de Mensaje: external o internal |
mcp_connection
Se envía cuando el agente necesita que el usuario final conecte o autorice uno o más servidores MCP antes de poder continuar. Este evento solo está disponible en modo streaming.
| Campo | Descripción |
|---|---|
connection_server_list | Servidores MCP que requieren una acción de conexión. Cada servidor incluye mcp_server_id, mcp_server_name y, opcionalmente, auth_url |
user_action_deadline_unix | Marca de tiempo Unix en la que vence la acción de usuario de conexión |
mcp_connection_resolved
Se envía cuando la acción de usuario de conexión MCP se ha resuelto o ha expirado.
No hay campos adicionales además de los campos comunes con ámbito de Ejecución.
warning
Se envía para advertencias no críticas durante una Ejecución.
| Campo | Descripción |
|---|---|
message | Advertencia no crítica legible por humanos |
code | Código de advertencia opcional |
stream_error
Se envía cuando una Ejecución falla. Puede seguir un Evento final stream_ended con success:false y stop_reason:"error".
| Campo | Descripción |
|---|---|
code | Código de error |
message | Mensaje de error legible por humanos |
stream_ended
Se envía una vez cuando la ejecución finaliza. Este es el evento final de la transmisión.
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}
Ejemplo de fallo:
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":false,"stop_reason":"user_cancelled","usage":{"cost":"0.0012"}}
| Campo | Descripción |
|---|---|
success | Indica si la ejecución se completó correctamente |
stop_reason | Motivo terminal de la ejecución: end_run, user_cancelled, user_action_timeout o error |
usage | Objeto de uso para esta solicitud. Actualmente incluye cost cuando está disponible |
ping
Fotogramas de keepalive enviados cada 15 segundos para evitar tiempos de espera de proxy/CDN. Ignórelos en su cliente.
Integración con servidor MCP
Conecte sus agentes a herramientas externas mediante el Model Context Protocol (MCP):
- Servidores MCP administrados por Jenova: servidores alojados por Jenova para búsqueda, recuperación de contenido, generación de documentos y otras capacidades integradas
- Servidores MCP remotos: otros servidores MCP remotos configurados para su Agente
Los servidores MCP deben configurarse en el panel de control al crear o editar su Agente. Para usar su propio servidor MCP, agréguelo a un Agente personalizado y luego invoque a ese Agente a través de la API. La API ejecuta las Herramientas habilitadas en la configuración del Agente; no se requiere configuración adicional en las solicitudes a la API.
Cuando un Agente usa Herramientas MCP durante una respuesta, se envían Eventos de progreso en la transmisión a medida que ocurren:
event: stream_progress
data: {"session_id":"ses_...","run_id":"run_...","state":"running","label":"Searching Google"}
Si el agente necesita que el usuario final conecte o autorice un servidor MCP durante la ejecución, las respuestas en streaming pueden incluir los eventos mcp_connection y mcp_connection_resolved. Presente la lista de servidores de conexión a su usuario final y abra la auth_url proporcionada cuando esté presente. Mantenga abierto el stream SSE mientras el usuario conecta o autoriza el servidor.
Después de la autorización, Jenova almacena el token, la ventana de autorización muestra una página de finalización y la misma Ejecución continúa automáticamente. El Usuario final no necesita volver a enviar el Mensaje.
Si el usuario final no conecta, autoriza, omite o silencia antes de user_action_deadline_unix, la ejecución finaliza con stop_reason:"user_action_timeout". También puede cancelar la ejecución activa con POST /sessions/{session_id}/cancel.
Almacene la auth_url en el lado del cliente. Si el cliente se desconecta durante la autorización, la URL sigue siendo válida hasta user_action_deadline_unix. Para solicitudes persistentes, vuelva a conectarse con Obtener estado de la ejecución, o recupere los mensajes después de que finalice la ejecución.
Las solicitudes sin streaming (stream: false) no admiten acciones de usuario de conexión MCP; use streaming para agentes que puedan necesitar esta interacción.
Omitir conexión MCP
POST /sessions/{session_id}/mcp/connection/skip
Descarta una acción de usuario de conexión MCP pendiente y permite que la ejecución continúe sin esa conexión.
Para silenciar futuras solicitudes de conexión para un servidor para el mismo usuario de la API, incluya mcp_server_id y mute. Los valores admitidos son 24h y forever.
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
run_id | string | Sí | ID de la ejecución activa proveniente del evento mcp_connection |
mcp_server_id | string | No | Obligatorio con mute; use el mcp_server_id del evento |
mute | string | No | 24h o forever |
Respuesta 204 No Content
El stream emite mcp_connection_resolved, y luego la ejecución continúa con el mismo run_id.
Errores
| Estado | Código | Condición |
|---|---|---|
| 400 | bad_request | Falta run_id, no hay ejecución activa, o no hay conexión MCP para omitir |
| 400 | bad_request | mute no válido, o falta mcp_server_id cuando se establece mute |
| 404 | session_not_found | La Sesión no existe |
| 404 | session_not_owned | No coincide con el user proporcionado |
| 409 | stale_run | run_id no coincide con la Ejecución activa |
Facturación
Todos los costos se deducen de su saldo de Créditos de desarrollador. Consulte el Uso y recargue Créditos en www.jenova.ai/platform.
Precios
| Operación | Costo |
|---|---|
| Crear Sesión | $0.01 fijo por cada Sesión persistente, incluidas las Sesiones creadas implícitamente mediante POST /messages |
| Bifurcar Sesión | $0.05 fijo |
| Enviar Mensaje | Variable (ver más abajo) |
El costo de un Mensaje depende de:
- Modelo: distintos Modelos tienen distintos costos por token
- Longitud del contexto: las Sesiones más largas consumen más tokens de entrada por solicitud
- Complejidad del flujo de trabajo: los flujos de trabajo más largos y el uso intensivo de Herramientas (búsqueda web, generación de archivos, análisis de documentos) aumentan el consumo total de tokens
El costo real se devuelve como stream_ended.usage.cost en las solicitudes con Transmisión y como usage.cost en las solicitudes JSON sin Transmisión.
Retenciones de créditos
Cada nueva Ejecución de Mensaje coloca una retención de $0.50 sobre su saldo de Créditos antes de que comience la ejecución. Esto reserva fondos para la Ejecución. Los Mensajes de seguimiento en cola dentro de una Ejecución activa no generan retenciones adicionales; el Uso de la Ejecución activa se verifica contra su saldo restante.
Cuando la Ejecución se completa, la retención se liquida al costo real y se libera la diferencia. Las Ejecuciones canceladas y fallidas solo se cobran por el Uso ya incurrido. Si una solicitud falla antes de llegar al Modelo, se libera la retención completa.
Esto significa que su saldo disponible puede aparecer temporalmente más bajo durante las solicitudes en curso. Necesita al menos $0.50 de saldo disponible para enviar un Mensaje a una Sesión existente o para enviar un Mensaje efímero. Una primera solicitud persistente POST /messages crea una Sesión y necesita al menos $0.51 para cubrir la retención del Mensaje más la tarifa de creación de la Sesión.
Límites de solicitudes
Toda cuenta de desarrollador está sujeta a tres dimensiones de Límite de solicitudes:
| Dimensión | Valor predeterminado | Descripción |
|---|---|---|
| RPM (Solicitudes Por Minuto) | 60 | Ventana fija por minuto |
| RPD (Solicitudes Por Día) | 1,000 | Ventana fija por día |
| Concurrentes | 5 | Número máximo de solicitudes simultáneas en curso |
Las solicitudes GET y HEAD no consumen espacios concurrentes. cancel, undo y mcp/connection/skip tampoco consumen espacios concurrentes, por lo que estas operaciones siguen estando disponibles cuando todos los espacios están en uso. Estas solicitudes siguen contando para RPM y RPD.
Encabezados de respuesta
Las respuestas autenticadas de la API incluyen encabezados de límite de solicitudes:
| Encabezado | Descripción |
|---|---|
X-RateLimit-Limit | Su límite de RPM |
X-RateLimit-Remaining | Solicitudes restantes en la ventana del minuto actual |
X-RateLimit-Reset | Marca de tiempo Unix en la que se restablece la ventana actual |
Retry-After | Segundos que se deben esperar antes de reintentar (solo en 429) |
Cuando se supera un límite, la API devuelve 429 Too Many Requests:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after 12 seconds."
}
}
Manejo de errores
Los errores HTTP inmediatos y los errores de Ejecución sin Transmisión siguen un formato coherente:
{
"error": {
"code": "error_code_string",
"message": "Human-readable description"
}
}
Los mensajes de error se localizan según el parámetro lang (consulte Localización).
Los errores de Ejecución en Transmisión se entregan como Eventos stream_error. Una Ejecución fallida puede aún enviar un Evento final stream_ended con success:false y stop_reason establecido. Los errores de Ejecución sin Transmisión también pueden incluir un objeto usage de nivel superior cuando hay datos de costo disponibles.
Los errores específicos de cada punto de conexión se documentan directamente en cada punto de conexión.
Errores de Ejecución después del inicio
Los errores de Ejecución aparecen después de que una Ejecución de Mensaje ya se ha iniciado. En modo de Transmisión, aparecen como Eventos stream_error y pueden ir seguidos de stream_ended con success:false. En modo sin Transmisión, se devuelven como una respuesta de error en JSON con el Código de estado HTTP que se indica a continuación.
| Código de estado HTTP sin Transmisión | Código | Descripción |
|---|---|---|
| 400 | content_policy_violation | El proveedor del Modelo rechazó la solicitud por motivos de política de contenido |
| 404 | session_not_found | La Sesión se eliminó antes de que la Ejecución pudiera ejecutarse |
| 409 | busy | La Sesión quedó ocupada o temporalmente no disponible antes de que la Ejecución pudiera iniciarse |
| 413 | total_image_size_exceeded | El tamaño combinado de las imágenes supera el límite por solicitud del Modelo |
| 500 | internal_error | Fallo inesperado de la Ejecución |
| 502 | llm_api_error | Error de la API del proveedor del Modelo o del Modelo subyacente |
Paginación
Los puntos de conexión de listado utilizan paginación basada en cursor:
{
"items": [],
"next_cursor": "eyJ2IjoxLCJrIjoiY3VyXzAyIn0",
"has_more": true
}
| Parámetro | Tipo | Valor predeterminado | Máx. | Descripción |
|---|---|---|---|---|
limit | integer | 20 | 100 | Número de elementos por página |
cursor | string | - | - | Cursor opaco proveniente de un next_cursor anterior |
Pase next_cursor como el Parámetro de consulta cursor para obtener la página siguiente. Cuando has_more es false, no hay más resultados.
Localización
Todos los puntos de conexión aceptan un Parámetro de consulta opcional lang para controlar el idioma de los mensajes de error y de cualquier contenido localizado.
| Origen | Prioridad | Ejemplo |
|---|---|---|
Parámetro de consulta lang | Más alta | ?lang=zh |
Encabezado Accept-Language | Alternativa | Accept-Language: ja |
| Valor predeterminado | Más baja | Inglés (en) |
Puede añadir ?lang=xx a cualquier URL de solicitud:
POST /sessions?lang=zh
GET /sessions/ses_abc123/messages?lang=ja
Idiomas admitidos: en, zh, ja, ko, es, fr, de, it, pt, ru, id, th, vi
Privacidad y datos
Jenova no utiliza los prompts, salidas, historial de conversaciones, archivos cargados, instrucciones de Agentes ni Bases de conocimientos de la API para entrenar los Modelos de Jenova.
En el caso de proveedores de Modelos externos, Jenova utiliza canales de API comerciales, configuraciones de cuenta, compromisos contractuales o mecanismos de exclusión destinados a evitar que el contenido de los clientes se utilice para entrenar los Modelos de dichos proveedores.
Jenova almacena y procesa los datos de la API utilizando infraestructura ubicada en Estados Unidos. Los proveedores externos pueden procesar datos en otras jurisdicciones, según se describe en la Política de Privacidad y las Condiciones de Uso.
Para obtener información completa, consulte las Condiciones de Uso, la Política de Privacidad y la Política de Uso.
Soporte
- Panel de control: www.jenova.ai/platform
- Correo electrónico: [email protected]