API HTTP
El servidor HTTP de Pillbox expone una API REST para la interfaz web e integraciones personalizadas. Inicia el servidor con pillbox serve start (puerto por defecto: 4242).
URL base: http://pillbox.local:4242/api
Todas las respuestas usan un sobre JSON uniforme:
{ "ok": true, "data": { ... } }{ "ok": false, "error": "not_found", "message": "..." }Bottles
Sección titulada «Bottles»GET /bottles
Sección titulada «GET /bottles»Devuelve todos los bottles registrados en el registro global.
Respuesta: array de objetos Bottle.
POST /bottles
Sección titulada «POST /bottles»Registra un nuevo bottle y lo añade al registro global.
Cuerpo de la petición:
{ "name": "mi-proyecto", "display_name": "Mi Proyecto", "directory": "/home/usuario/proyectos/mi-proyecto", "scope": "local"}Respuesta: 201 Created con el objeto Bottle creado.
GET /bottles/:bottle_id
Sección titulada «GET /bottles/:bottle_id»Devuelve un bottle por UUID v7.
Respuesta: objeto Bottle o 404.
Prescriptions
Sección titulada «Prescriptions»Las prescriptions están anidadas bajo su bottle.
GET /bottles/:bottle_id/prescriptions
Sección titulada «GET /bottles/:bottle_id/prescriptions»Devuelve el historial de prescriptions para un bottle.
| Query param | Tipo | Descripción |
|---|---|---|
limit | integer | Máximo de resultados (por defecto: 50) |
Respuesta: array de objetos Prescription.
POST /bottles/:bottle_id/prescriptions
Sección titulada «POST /bottles/:bottle_id/prescriptions»Abre una nueva prescription para un bottle.
Cuerpo de la petición:
{ "title": "Implementar login OAuth"}Respuesta: 201 Created con el objeto Prescription.
Error: 409 Conflict con la prescription actualmente abierta si ya existe una.
GET /bottles/:bottle_id/prescriptions/:rx_id
Sección titulada «GET /bottles/:bottle_id/prescriptions/:rx_id»Devuelve una prescription por UUID v7.
Respuesta: objeto Prescription o 404.
PATCH /bottles/:bottle_id/prescriptions/:rx_id
Sección titulada «PATCH /bottles/:bottle_id/prescriptions/:rx_id»Cierra una prescription abierta (establece ended_at a ahora).
Respuesta: objeto Prescription actualizado o 404.
DELETE /bottles/:bottle_id/prescriptions/:rx_id
Sección titulada «DELETE /bottles/:bottle_id/prescriptions/:rx_id»Descarta una prescription (soft delete). La prescription y sus pills quedan archivadas con deleted_at establecido.
Respuesta: { "discarded": true } o 404.
DELETE /bottles/:bottle_id/prescriptions/:rx_id/purge
Sección titulada «DELETE /bottles/:bottle_id/prescriptions/:rx_id/purge»Elimina permanentemente una prescription y todos sus datos relacionados: entradas de dispense_log y todas sus pills.
Respuesta: { "purged": true } o 404.
Las pills están anidadas bajo su prescription, que está anidada bajo su bottle.
GET /bottles/:bottle_id/prescriptions/:rx_id/pills
Sección titulada «GET /bottles/:bottle_id/prescriptions/:rx_id/pills»Devuelve todas las pills vinculadas a una prescription.
Respuesta: array de objetos Pill o 404 si la prescription no existe.
POST /bottles/:bottle_id/prescriptions/:rx_id/pills
Sección titulada «POST /bottles/:bottle_id/prescriptions/:rx_id/pills»Crea una nueva pill.
Cuerpo de la petición:
{ "title": "Migrado a autenticación JWT", "content": "Reemplazado express-session con jsonwebtoken...", "compound": "decision"}Respuesta: 201 Created con el objeto Pill.
GET /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id
Sección titulada «GET /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id»Devuelve una pill por ID entero.
Respuesta: objeto Pill o 404.
PATCH /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id
Sección titulada «PATCH /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id»Actualiza el título, contenido o compound de una pill. Todos los campos son opcionales.
Cuerpo de la petición:
{ "title": "Título actualizado", "content": "Contenido actualizado", "compound": "architecture"}Respuesta: objeto Pill actualizado o 404.
DELETE /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id
Sección titulada «DELETE /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id»Descarta una pill (soft delete). El registro queda archivado con deleted_at establecido.
Respuesta: objeto Pill archivado o 404.
DELETE /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id/purge
Sección titulada «DELETE /bottles/:bottle_id/prescriptions/:rx_id/pills/:pill_id/purge»Elimina permanentemente una pill.
Respuesta: { "purged": true } o 404.
GET /pills/search
Sección titulada «GET /pills/search»Búsqueda de texto completo sobre pills de todos los bottles.
| Query param | Tipo | Descripción |
|---|---|---|
query | string | Consulta de búsqueda (requerido) |
bottle_id | string (UUID v7) | Restringir a un bottle específico |
compound | string | Filtrar por tipo de compound |
limit | integer | Máximo de resultados (por defecto: 20) |
Respuesta: array de objetos SearchResult con id, title, snippet, rank, compound, prescription_id y bottle_id.
Contexto
Sección titulada «Contexto»GET /bottles/:bottle_id/context
Sección titulada «GET /bottles/:bottle_id/context»Devuelve el índice navegable de prescriptions de un bottle — útil para poblar el system prompt de un agente.
| Query param | Tipo | Descripción |
|---|---|---|
limit | integer | Máx. prescriptions a devolver (por defecto: 30) |
Respuesta:
{ "ok": true, "data": { "context": "...", "prescription_count": 12 }}Capsules
Sección titulada «Capsules»Las capsules usan la base de datos global (~/.pillbox/pillbox.db) independientemente de qué bottle esté activo.
POST /capsules
Sección titulada «POST /capsules»Crea una nueva capsule.
Cuerpo de la petición:
{ "title": "Convención de nombres de ramas Git", "content": "Siempre añadir prefijo feat/ a las ramas de funcionalidad...", "compound": "convention"}Respuesta: 201 Created con el objeto Capsule.
GET /capsules
Sección titulada «GET /capsules»Lista capsules, incluyendo las archivadas (con deleted_at establecido). Las activas aparecen primero.
| Query param | Tipo | Descripción |
|---|---|---|
compound | string | Filtrar por tipo de compound |
limit | integer | Máximo de resultados |
Respuesta: array de objetos Capsule.
GET /capsules/:id
Sección titulada «GET /capsules/:id»Devuelve una capsule por ID entero, incluyendo si está archivada.
Respuesta: objeto Capsule o 404.
PATCH /capsules/:id
Sección titulada «PATCH /capsules/:id»Actualiza el título o contenido de una capsule.
Cuerpo de la petición:
{ "title": "Título actualizado", "content": "Contenido actualizado"}Respuesta: objeto Capsule actualizado o 404.
DELETE /capsules/:id
Sección titulada «DELETE /capsules/:id»Descarta una capsule (soft delete). El registro queda archivado con deleted_at establecido.
Respuesta: objeto Capsule archivado o 404.
DELETE /capsules/:id/purge
Sección titulada «DELETE /capsules/:id/purge»Elimina permanentemente una capsule.
Respuesta: { "purged": true } o 404.
GET /capsules/search
Sección titulada «GET /capsules/search»Búsqueda de texto completo sobre capsules.
| Query param | Tipo | Descripción |
|---|---|---|
query | string | Consulta de búsqueda (requerido) |
compound | string | Filtrar por tipo de compound |
limit | integer | Máximo de resultados (por defecto: 20) |
Respuesta: array de objetos SearchResult.
GET /version
Sección titulada «GET /version»Devuelve la versión del servidor en ejecución.
Respuesta:
{ "ok": true, "data": { "version": "0.15.2" } }Códigos de estado HTTP
Sección titulada «Códigos de estado HTTP»| Código | Significado |
|---|---|
200 OK | Lectura o actualización exitosa |
201 Created | Recurso creado |
404 Not Found | El recurso no existe |
409 Conflict | Ya hay una prescription abierta para este bottle |
422 Unprocessable Entity | Falló la validación del cuerpo de la petición |
500 Internal Server Error | Error inesperado del servidor |