API HTTP de Gateway
El gateway expone una superficie REST junto con la CLI local. Todo lo que se puede establecer con zeroclaw config get/set/list/init/migrate también es accesible vía HTTP, por lo que el panel de control, las herramientas de terceros y la CLI utilizan el mismo núcleo de mutación de Config subyacente.
Esta página es una descripción general de alto nivel. Las definiciones a nivel de campo, las formas de las solicitudes y respuestas, y los formularios “Try it out” para el subconjunto de OpenAPI actualmente documentado se encuentran en /api/docs en un gateway en ejecución. Esos esquemas provienen de tipos en tiempo de ejecución, pero el inventario de rutas se ensambla por separado y aún no cubre todas las rutas registradas por el gateway. El router en crates/zeroclaw-gateway/src/lib.rs sigue siendo la autoridad para la superficie completa en vivo.
Registrado en el issue #6175.
Autenticación
Los valores de configuración y las mutaciones descritas en esta página están controlados por el emparejamiento existente y la autenticación mediante bearer token. El descubrimiento de la estructura a través de /api/docs, /api/openapi.json, y la opción OPTIONS de configuración es público. Un código de emparejamiento de primer uso se imprime cuando el daemon se inicia; las llamadas autenticadas posteriores envían el bearer token derivado en el encabezado Authorization. El explorador Scalar en /api/docs expone un panel “Authentication” donde se pega el token antes de realizar llamadas autenticadas.
Vinculado a local de forma predeterminada. El acceso a través de la red requiere terminación TLS en el gateway o delante de él; los endpoints por propiedad y PATCH no son seguros para exponer sin autenticación, independientemente de la postura de TLS.
Descubriendo la superficie
Dos endpoints responden a la pregunta “¿qué puedo hacer aquí?”:
OPTIONS /api/configdevuelve el JSON Schema para el tipo de configuración completa. Estático por compilación; los clientes deben almacenar en caché según el encabezadoETag. Su encabezadoAllowactual aún lista elPUTheredado, que el enrutador no registra.OPTIONS /api/config/prop?path=<dotted>devuelve el fragmento de esquema para una ruta específica conAllow: GET, PUT, DELETE, OPTIONS. Devuelve 404 si la ruta no existe en el esquema.
OPTIONS devuelve las capacidades. GET /api/config/prop y GET /api/config/list devuelven los valores actuales del usuario. Los formularios del panel emiten OPTIONS una vez al cargarse para conocer los tipos y las restricciones, luego GET para rellenar los campos y, por último, PUT/PATCH para escribir. Un GET /api/config de compatibilidad también devuelve una instantánea de toda la configuración con los secretos enmascarados, de modo que las páginas del panel incluidas más antiguas no fallen frente a puertas de enlace más nuevas. Los clientes nuevos deberían preferir la superficie por propiedad, ya que incluye metadatos de campo y un manejo explícito de secretos.
Las solicitudes preflight de CORS (aquellas que incluyen Access-Control-Request-Method) reciben la respuesta preflight estándar y se interrumpen antes de que se devuelva el cuerpo del esquema.
CRUD por propiedad
| Método | Ruta | Propósito |
|---|---|---|
GET | /api/config | Instantánea de compatibilidad de la configuración completa con los secretos enmascarados; los clientes nuevos deberían preferir la interfaz por propiedad. |
PATCH | /api/config | Aplica un documento JSON Patch (RFC 6902) de forma atómica. |
OPTIONS | /api/config | Esquema JSON de configuración completa (capacidades, no valores). |
GET | /api/config/prop?path=... | Lee un campo. Los secretos devuelven solo {path, populated}. |
PUT | /api/config/prop | Escribe un campo. Cuerpo: {path, value, comment?}. Los secretos responden solo con {path, populated: true}. |
DELETE | /api/config/prop?path=... | Restablece un campo a su valor predeterminado. Los secretos responden con {path, populated: false}. |
OPTIONS | /api/config/prop?path=... | Fragmento de esquema por campo. |
GET | /api/config/list?prefix=... | Enumera cada ruta accesible con su tipo y categoría. Las entradas secretas incluyen {path, populated, is_secret: true} y no tienen valor. |
POST | /api/config/init?section=... | Instancia con valores predeterminados las secciones anidadas que sean None. Los alias de mapas dinámicos no se crean aquí; usa POST /api/config/map-key. |
POST | /api/config/migrate | Aplica la migración del esquema en disco en el lugar. Refleja zeroclaw config migrate. |
Escrituras atómicas por lotes: JSON Patch
PATCH /api/config acepta un documento JSON Patch (RFC 6902). Las operaciones de configuración admitidas son add, replace, remove y test. ZeroClaw también acepta una extensión comment para anotaciones de configuración. Las operaciones de configuración se ejecutan sobre una copia en memoria; una vez que todas las operaciones se han aplicado, Config::validate() se ejecuta una vez sobre el resultado. Si la validación es exitosa, el nuevo estado se persiste y se intercambia. Si alguna operación o la validación final falla, el estado en disco y en memoria permanece sin cambios. Las anotaciones de comentarios se aplican después del guardado de forma no crítica y en la medida de lo posible.
move y copy devuelven 400 op_not_supported porque la reescritura segura del grafo de referencias no forma parte de esta superficie. test contra una ruta #[secret] se rechaza con secret_test_forbidden: un resultado diferencial sería la única señal que un cliente podría leer, y eso filtraría el valor.
Sintaxis de ruta: JSON Pointer (/agents/researcher/model_provider) o la forma con puntos (agents.researcher.model_provider). Ambas se aceptan; el servidor las normaliza.
El equivalente en la CLI es zeroclaw config patch <file-or-stdin>, que aplica el mismo conjunto de operaciones sobre el Config local y devuelve la misma estructura de respuesta estructurada (--json para scripts).
Secretos: solo escritura a través de HTTP
Las lecturas por propiedad nunca exponen campos secretos (los marcados con #[secret] o #[derived_from_secret] en el esquema). Sus respuestas solo contienen {populated: bool}, sin valor, longitud, sustituto enmascarado ni hash. En cambio, la interfaz de compatibilidad GET /api/config serializa toda la configuración después de aplicar MaskSecrets, por lo que los campos secretos solo pueden aparecer allí como marcadores de posición enmascarados. Ninguna de las dos interfaces de lectura de la configuración devuelve el valor secreto subyacente.
PUT y PATCH escriben el nuevo valor del secreto y responden con {populated: true}; DELETE lo borra y responde con {populated: false}. No existe ninguna ruta HTTP para recuperar un secreto por ningún medio.
Códigos de error estables
Los errores devuelven JSON con un campo code estable más un message legible para humanos. Los frontends y scripts coinciden con el código; la UI coincide con la ruta.
| Código | Estado | Significado |
|---|---|---|
path_not_found | 404 | La propiedad solicitada no existe en el esquema. |
validation_failed | 400 | El validador de configuración completa rechazó el estado propuesto. |
dangling_reference | 400 | Una referencia de alias configurada (p. ej., agents.<x>.model_provider) nombra un destino inexistente (p. ej., providers.models.<type>.<alias>). |
value_type_mismatch | 400 | El valor JSON enviado no se puede convertir al tipo de destino. |
op_not_supported | 400 | La operación de JSON Patch es move / copy / desconocida. |
secret_test_forbidden | 400 | La operación test de JSON Patch apuntó a una ruta secreta. |
config_changed_externally | 409 | La configuración en disco se desincronizó de la copia en memoria. (Consulta detección de desincronización). |
reload_failed | 500 | El guardado se realizó correctamente, pero la recarga del daemon no pudo aplicar el nuevo estado; se revirtió el contenido en disco. |
internal_error | 500 | Fallo del lado del servidor sin clasificar. |
Exploración en vivo
Una vez que la puerta de enlace esté en ejecución, navega a http://<gateway-host>:<port>/api/docs para acceder al explorador de API de Scalar. La especificación sin procesar está disponible en /api/openapi.json para otros visores compatibles.
El panel de autenticación del explorador se vincula al esquema bearerAuth declarado en la especificación; pega allí tu token bearer derivado del emparejamiento antes de realizar llamadas en vivo. El atajo de la CLI para la URL es zeroclaw config docs.
Si el bundle de Scalar no puede cargarse desde la CDN (instalación offline / air-gapped), la página se degrada correctamente y te dirige al spec sin procesar en /api/openapi.json para que puedas usar cualquier visor compatible (Insomnia, Postman, Swagger UI, etc.).
Contrato de flujo de eventos
GET /api/events es un flujo sin procesar de Server-Sent Events de eventos de ejecución observables. No es una línea de tiempo de ciclo de vida deduplicada con una fila por turno.
Los gestores de gateway, el manejo de webhooks, las tareas de cron/heartbeat y los observadores del bucle del agente pueden publicar eventos con forma de ciclo de vida en la misma ruta de difusión. Los clientes deben tratar el flujo como un registro de observación de solo anexado. Si un panel desea una línea de tiempo de turnos compacta, debe agrupar o desduplicar según los identificadores presentes en la carga útil del evento, en lugar de suponer que cada fotograma agent_start, llm_request o agent_end aparece solo una vez.
GET /api/events/history reproduce los eventos recientes retenidos del mismo búfer, comenzando por los más antiguos. Es una ventana de reconexión para los suscriptores, no un almacén canónico de ciclo de vida independiente.