REST API
La superficie HTTP que expone ObjectOS — generada a partir de tus metadatos, delimitada por permisos y descrita con OpenAPI.
Cada objeto que declaras obtiene automáticamente un conjunto completo de endpoints REST.
Cada acción se convierte en un POST. Cada flujo se convierte en un POST a
/flows/.... No hay que escribir ni desplegar una capa de API aparte.
URL base: https://<your-host>/api/v1.
La especificación OpenAPI está disponible en vivo en /api/v1/openapi.json.
Autenticación
ObjectOS utiliza Better Auth. Todas las rutas
bajo /api/v1 requieren una sesión autenticada, salvo que estén marcadas
explícitamente como públicas (consulta Formularios públicos). Los métodos de autenticación
se configuran en apps/<app>/auth.config.ts — normalmente una cookie de sesión o
un token bearer obtenido de /api/v1/auth/sign-in.
Los permisos se comprueban por ruta y por registro. Las rutas anotadas
a continuación con una clave de permiso (p. ej. ai:chat) invocan
requirePermission(...); el acceso a nivel de registro lo aplica RBAC +
seguridad a nivel de fila + seguridad a nivel de campo dentro del motor de datos.
Discovery
| Ruta | Método | Propósito |
|---|---|---|
/api/v1 | GET | Descubrimiento de servicios — lista todas las rutas registradas, la versión y el modo de delimitación |
/api/v1/discovery | GET | Alias explícito del documento de descubrimiento anterior |
/api/v1/openapi.json | GET | Especificación OpenAPI 3.0 de cada endpoint del runtime en ejecución |
/api/v1/search | GET | Búsqueda de texto completo en los campos indexables de todos los objetos |
Restringir la superficie de la API
Los endpoints autogenerados se gobiernan por objeto, de modo que puedes retirar un objeto de la API o hacerlo de solo lectura sin escribir código de rutas:
apiEnabled(boolean, por defectotrue): establécelo enfalsepara omitir el objeto de la superficie REST por completo. Las solicitudes a sus rutas devuelven 404.apiMethods(lista blanca opcional): cuando se establece, solo son accesibles las operaciones listadas; cualquier otra operación se rechaza en la capa REST. Valores permitidos:get,list,create,update,delete,upsert,bulk,aggregate,history,search,restore,purge,import,export.
// Un objeto de referencia de solo lectura, nunca escribible por la API:
defineObject({
name: 'exchange_rate',
apiMethods: ['get', 'list'],
// ...fields
})
// Un objeto interno que la API nunca expone:
defineObject({
name: 'sync_cursor',
apiEnabled: false,
// ...fields
})Ambos se aplican ahora en la capa REST (ADR-0049): las versiones anteriores analizaban estas propiedades pero no las aplicaban.
Datos — /api/v1/data/*
CRUD + consultas avanzadas para cada objeto que declaras. :object es el
name del objeto (snake_case).
| Ruta | Método | Propósito |
|---|---|---|
/data/:object | GET | Listar / consultar — pasa where, orderBy, limit, offset, cursor, expand, select como parámetros de consulta |
/data/:object/query | POST | Consulta avanzada — cuerpo ObjectQL completo con groupBy + aggregations (consulta ObjectQL) |
/data/:object/:id | GET | Obtener un registro. Admite ?select= y ?expand= |
/data/:object | POST | Crear. Devuelve 201 con el nuevo registro |
/data/:object/:id | PATCH | Actualizar. Pasa la cabecera If-Match: <version> (o expectedVersion en el cuerpo) para concurrencia optimista — 409 CONCURRENT_UPDATE en caso de conflicto |
/data/:object/:id | DELETE | Eliminar. Misma regla de If-Match |
/data/:object/import | POST | Importación masiva (CSV o JSON). Cuerpo: { format, csv? | rows?, mapping?, dryRun? }. Máximo 5.000 filas por solicitud |
/data/:object/export | POST | Exportar registros como csv / xlsx / pdf / json |
/data/:object/:id/shares | GET / POST | Compartición por registro — listar concesiones, conceder acceso |
/data/:object/:id/shares/:shareId | DELETE | Revocar una compartición |
/data/lead/:id/convert | POST | Conversión de lead al estilo Salesforce (plantilla CRM). Cuerpo: { accountId?, contactId?, createOpportunity? } |
Ejemplo rápido
GET /api/v1/data/support_ticket?where={"status":{"$eq":"open"}}&orderBy=-created_at&limit=20
Authorization: Bearer <token>{
"items": [ { "id": "...", "subject": "...", "status": "open" } ],
"total": 137,
"nextCursor": "eyJpZCI6IjAxSDA..."
}AI — /api/v1/ai/*
Los endpoints sobre los que se apoyan el AI Builder y tus agentes.
| Ruta | Método | Permiso | Propósito |
|---|---|---|---|
/ai/models | GET | ai:chat | Listar los modelos disponibles de los proveedores configurados |
/ai/chat | POST | ai:chat | Completado de chat de un solo paso (síncrono) |
/ai/chat/stream | POST | ai:chat | Chat en streaming (SSE) |
/ai/complete | POST | ai:chat | Endpoint de completado en bruto |
/ai/conversations | GET / POST | ai:chat | Listar / crear conversaciones persistentes |
/ai/conversations/:id | GET / DELETE | ai:chat | Leer / eliminar una conversación |
/ai/conversations/:id/messages | POST | ai:chat | Añadir un mensaje del usuario y ejecutar el agente |
/ai/pending-actions | GET | ai:read | La cola de aprobación HITL — mutaciones que la IA ha propuesto |
/ai/pending-actions/:id | GET | ai:read | Inspeccionar una mutación en cola |
/ai/pending-actions/:id/approve | POST | ai:approve | Aplicar la mutación |
/ai/pending-actions/:id/reject | POST | ai:approve | Descartarla |
La separación entre ai:read y ai:approve es la primitiva de seguridad
que hace que el AI Builder sea seguro para los usuarios finales.
Acciones — /api/v1/actions/*
Cada *.action.ts que declaras se convierte en un endpoint.
| Ruta | Método | Propósito |
|---|---|---|
/actions/:action | POST | Invocar la acción. El cuerpo es el esquema de entrada de la acción. Los permisos y la validación de entrada provienen de la declaración de la acción |
Cada acción también se expone a la IA como una herramienta action_<name> — consulta
Acciones.
Flujos — /api/v1/flows/*
| Ruta | Método | Propósito |
|---|---|---|
/flows/:flow/start | POST | Iniciar un flujo. El cuerpo es la entrada del flujo |
/flows/:flow/runs/:runId | GET | Estado + salida de los pasos de un flujo en ejecución / completado |
/flows/:flow/runs/:runId/cancel | POST | Cancelar una ejecución en curso |
Metadatos — /api/v1/meta/*
Introspección de solo lectura de los metadatos del runtime en ejecución. Útil para herramientas y para la Console.
| Ruta | Método | Propósito |
|---|---|---|
/meta | GET | Todos los tipos de metadatos (object, view, action, flow, agent, …) |
/meta/:type | GET | Listar los elementos de un tipo. Filtra con ?package=<id> |
/meta/:type/:name | GET | Obtener un elemento. ?layers=true devuelve la vista de diferencias de 3 estados (base / package / overlay) |
/meta/:type/:name/references | GET | Encontrar todos los elementos de metadatos que hacen referencia a este |
/meta/:type/:name/history | GET | Registro de auditoría de ese elemento |
/meta/:type/:section/:name | GET / POST | Leer / insertar o actualizar un elemento de metadatos seccionado |
/meta/:type/:section/:name | DELETE | Eliminar un elemento seccionado |
Compartición y aprobaciones
| Ruta | Método | Propósito |
|---|---|---|
/sharing/rules | GET / POST / DELETE | Gestionar reglas de compartición |
/sharing/rules/:idOrName/evaluate | POST | Ejecutar en seco una regla contra un contexto |
/approvals/processes | GET / POST | Definiciones de procesos de aprobación |
/approvals/requests | GET / POST | Enviar / listar solicitudes de aprobación |
/approvals/requests/:id/approve | POST | Decisión: aprobar |
/approvals/requests/:id/reject | POST | Decisión: rechazar |
Informes y búsqueda
| Ruta | Método | Propósito |
|---|---|---|
/reports | GET / POST / PATCH | CRUD de informes |
/reports/:id/run | POST | Ejecutar un informe — devuelve filas agregadas |
/reports/:id/schedule | POST | Programar entrega recurrente |
Formularios públicos
Las únicas rutas que son no autenticadas, habilitadas de forma opcional mediante
FormView.sharing.allowAnonymous.
| Ruta | Método | Autenticación |
|---|---|---|
/forms/:slug | GET | pública — devuelve el esquema del formulario |
/forms/:slug/submit | POST | pública — envía una respuesta |
Utilidades
| Ruta | Método | Permiso | Propósito |
|---|---|---|---|
/email/send | POST | email:send | Enviar un correo electrónico a través del proveedor configurado |
Envoltorio de errores
Toda respuesta distinta de 2xx sigue la misma forma:
{
"error": {
"code": "PERMISSION_DENIED",
"message": "Missing ai:approve on conversation 01H…",
"details": { "permission": "ai:approve", "subject": "01H…" }
}
}Códigos comunes: UNAUTHENTICATED, PERMISSION_DENIED,
VALIDATION_ERROR, NOT_FOUND, CONCURRENT_UPDATE,
RATE_LIMITED, INTERNAL.
Versionado
/api/v1 es la API estable. Los cambios incompatibles van a /api/v2 y
ambas se sirven en paralelo durante una versión menor. La versión actual y
el horizonte de obsolescencia están en GET /api/v1.
Véase también
- ObjectQL — el lenguaje de consulta utilizado por
/data/* - Tipos de campo — qué formas pueden adoptar los datos
- Build → Acciones — declarar endpoints personalizados
- Seguridad — qué comprueba cada ruta antes de ejecutarse