La API de Openbeehive
El servidor expone una API Connect-RPC definida en
Protocol Buffers bajo
proto/openbeehive/v1.
Cada RPC es accesible mediante HTTP/JSON plano, gRPC y gRPC-Web desde la misma
URL. La propia aplicación solo usa SyncService; los demás servicios existen
para scripts, sensores e integraciones.
URL base y forma de la ruta
La API es servida por el mismo proceso que la aplicación, en el mismo origen:
POST <origin>/openbeehive.v1.<Service>/<Method>
Por ejemplo https://app.openbeehive.org/openbeehive.v1.ApiaryService/ListApiaries
en el servicio alojado, o tu propio origen si te autoalojas.
Servicios servidos
Hay diez servicios registrados en el servidor (server/cmd/server/main.go):
| Servicio | RPC |
|---|---|
ApiaryService | CreateApiary, GetApiary, ListApiaries, UpdateApiary, DeleteApiary |
HiveService | CreateHive, GetHive, ListHives, UpdateHive, DeleteHive, RelocateHive |
QueenService | CreateQueen, ListQueens, UpdateQueen, DeleteQueen |
InspectionService | CreateInspection, ListInspections, DeleteInspection, AddInspectionPhoto, RemoveInspectionPhoto |
TaskService | CreateTask, ListTasks, SetTaskDone, DeleteTask |
TreatmentService | CreateTreatment, ListTreatments, DeleteTreatment |
HarvestService | CreateHarvest, ListHarvests, DeleteHarvest |
EventService | ListEvents |
StatsService | GetDashboard, GetHoneyStats |
SyncService | Pull, Push, Subscribe (stream desde el servidor) |
Cada RPC está acotado al espacio (tenant) activo del llamante. Los id de otro
espacio se comportan como id desconocidos (not_found).
Las escrituras pasan por la sincronización
Cada RPC de escritura (Create*, Update*, Delete*, RelocateHive,
SetTaskDone, AddInspectionPhoto, RemoveInspectionPhoto) se aplica
mediante la misma fusión por campo y se añade al mismo registro de cambios que
SyncService.Push. Una fila escrita a través de la API llega a todos los
dispositivos en su siguiente sincronización, y una edición posterior desde un
dispositivo se fusiona con ella campo a campo, exactamente igual que se
fusionan entre sí las ediciones de dos dispositivos. Las eliminaciones son
lógicas: la fila recibe una lápida (deleted = 1) y desaparece de las listas
y de la aplicación.
Las escrituras del lado del servidor reflejan los propios flujos de la
aplicación (server/internal/service/writer.go es una adaptación de
app/src/lib/local/history.ts), así que el historial que muestra un
dispositivo es el mismo tanto si un registro se introdujo en la aplicación
como a través de la API:
CreateHiveescribe la colmena, abre un intervalo de ubicación y registra un eventoCREATED. Las colmenas nuevas empiezan comoHIVE_STATUS_ACTIVE.RelocateHivecierra la ubicación abierta, abre una nueva en el colmenar de destino y registra un eventoMOVED.UpdateHivenunca mueve una colmena.CreateQueentermina el reinado de la reina activa de la colmena (active = false,replacedAtestablecido alintroducedAtde la nueva reina), registra los eventosQUEEN_REPLACEDyQUEEN_INTRODUCED, y deriva el color de marcado deyearcuando no envías ninguno.CreateInspectionyCreateTreatmentcongelan el colmenar y la reina reinante en ladatedel registro (un registro con fecha anterior se resuelve contra el historial de ubicaciones y de reinas) y registran un eventoINSPECTIONoTREATMENT.CreateHarvestcongela el colmenar y la reina reinante endatede la misma manera, escribe la fila de cosecha y registra un eventoHARVESTque llevaamountKgy el título<kg> kg <variety>(Honeycuandovarietyestá vacío).GetDashboardyGetHoneyStatssuman esos eventos, así que una cosecha publicada a través de la API cuenta al instante en las cifras de miel.amountKgdebe ser mayor que0.- Una tarea con
hiveIdoapiaryIdse sincroniza bajo ese colmenar y se comparte con todos los que lo ven; una tarea sin ninguno de los dos vive en el ámbito personal del llamante y llega solo a los dispositivos de ese usuario.
Las lecturas (Get*, List*, ListEvents, GetDashboard, GetHoneyStats)
consultan directamente las tablas del servidor. Muestran las escrituras de la
API al instante y las escrituras de los dispositivos en cuanto el dispositivo
las ha enviado.
Todavía no en la API
- No hay RPC para editar cosechas.
HarvestServicesolo tieneCreateHarvest,ListHarvestsyDeleteHarvest. Para corregir una cosecha, elimínala y créala de nuevo, o edítala en la aplicación. - No hay RPC de ubicaciones. Las ubicaciones las escriben
CreateHiveyRelocateHivey aparecen solo en el feed de sincronización. EventServicees de solo lectura. Los eventos los escriben los flujos anteriores y la aplicación.
Consulta el protocolo de sincronización para el formato de los cambios y el modelo de datos para las columnas detrás de cada mensaje.
Endpoints que no son RPC
Junto a los servicios RPC hay unos cuantos endpoints HTTP planos:
| Ruta | Propósito |
|---|---|
GET /healthz | Devuelve ok |
GET /files/<key> | Archivos almacenados, solo con el backend de blobs de sistema de archivos (BEEHIVE_BLOB_BACKEND=fs) |
POST /auth/signin, POST /auth/signup, GET /auth/verify | Cuentas de correo y contraseña (BEEHIVE_PASSWORD_AUTH=true) |
GET /auth/login, GET /auth/callback | OIDC (BEEHIVE_OIDC_PROVIDERS definido) |
/auth/webauthn/login/*, /auth/webauthn/enroll/*, /auth/webauthn/credentials* | Passkeys (BEEHIVE_WEBAUTHN_ENABLED=true) |
/auth/logout, /auth/me, /auth/instance, /auth/switch, /auth/accept-invite | Auxiliares de sesión y de espacio (tenant), presentes siempre que haya algún método de inicio de sesión habilitado |
GET /auth/api-keys, POST /auth/api-keys, POST /auth/api-keys/delete | Gestión de claves API (listar, crear, eliminar), presente siempre que haya algún método de inicio de sesión habilitado; solo con sesión, una clave no puede llamarlos |
/tenants/create, /tenants/invite, /tenants/invites, /tenants/invite/revoke, /tenants/delete | Administración de espacios, presente siempre que haya algún método de inicio de sesión habilitado |
POST /auth/demo-login | Solo con BEEHIVE_DEMO=true |
Los usan las pantallas de inicio de sesión y ajustes de la aplicación. No forman parte del contrato proto.
Autenticación
Cómo se autentica una solicitud depende de si la instancia tiene un método de inicio de sesión:
- Sin inicio de sesión configurado (autoalojado,
BEEHIVE_PASSWORD_AUTH=false,BEEHIVE_OIDC_PROVIDERSvacío,BEEHIVE_WEBAUTHN_ENABLED=false): cada solicitud se ejecuta como el usuario local fijo. No envíes credenciales. En una instancia así no hay claves API; tampoco hacen falta. - Inicio de sesión configurado: cada RPC necesita una clave API o un token
de sesión en
Authorization: Bearer <token>(la cookieobh_sessionse acepta para los tokens de sesión). Una solicitud sin un token válido recibe el código Connectunauthenticated(HTTP 401).
Claves API
Una clave API es la credencial recomendada para scripts, sensores e integraciones. Las claves se gestionan en la aplicación en Ajustes → Claves API (consulta Cuentas y espacios):
- Inicia sesión, cambia al espacio en el que el script debe escribir y abre Ajustes → Claves API.
- Escribe un nombre (por ejemplo
hive scale), elige los permisos (Lectura y escritura o Solo lectura) y una caducidad (No caduca, 30 días, 90 días o 1 año), y después toca Crear clave. La clave empieza porobhk_y se muestra una sola vez; cópiala ahora. El servidor almacena solo su hash SHA-256 y los primeros 12 caracteres para mostrarlos. - Envíala en cada RPC:
Authorization: Bearer obhk_...
Qué puede y qué no puede hacer una clave:
- Actúa como su propietario, con el rol del propietario, dentro del espacio que estaba activo cuando se creó la clave. No puede cambiar de espacio; crea una clave por espacio si un script necesita varios.
- Funciona solo en los RPC. Los endpoints
/auth/*y/tenants/*, incluida la propia gestión de claves, necesitan una sesión real: una clave no puede listar, crear ni eliminar claves. - Tiene uno de dos ámbitos, fijado al crearla. Una clave
write(la predeterminada) puede llamar a todos los RPC a los que puede llamar su propietario. Una clavereadsolo puede llamar a los RPC cuyo nombre empiece porGet,List,PulloSubscribe; cualquier otro RPC devuelve el código Connectpermission_denied(HTTP 403) con el mensajethis API key is read-only. - Caduca solo si estableces una caducidad:
expires_in_daysde0(nunca, el valor predeterminado) a3650. Pasadoexpires_at, cada RPC devuelveunauthenticated(HTTP 401) con el mensajeAPI key expired. Las claves caducadas permanecen en la lista hasta que las eliminas. - Deja de funcionar en el momento en que se elimina en Ajustes, y muere con la membresía: cuando el propietario abandona el espacio o es eliminado de él, la clave se rechaza.
- Cada uso marca
last_used_at, que se muestra como Último uso en Ajustes. - La cuenta de demostración no puede crear claves.
Los mismos endpoints que usa la aplicación están abiertos a un script autenticado con sesión:
GET /auth/api-keysdevuelve{"keys": [{id, name, prefix, scope, created_at, expires_at, last_used_at, mine}]}, solo tus propias claves en el espacio activo.scopees"write"o"read";expires_atylast_used_atson marcas de tiempo RFC 3339 onull;mineaquí es siempretrue.GET /auth/api-keys?tenant=1devuelve todas las claves del espacio activo, y cada fila lleva ademásuser_id,user_emaily un indicadormineque estrueen tus propias claves. Solo pueden llamarlo el propietario del espacio (el rol que la aplicación llama Admin) y el administrador de la instancia; cualquier otra persona recibe HTTP 403.POST /auth/api-keyscon{"name": "...", "scope": "write", "expires_in_days": 0}devuelve{id, name, prefix, scope, created_at, expires_at, token}.scopetoma por defecto"write"yexpires_in_days0(nunca) cuando se omiten. Cualquier otro ámbito, o una duración inferior a0o superior a3650, responde HTTP 400.POST /auth/api-keys/deletecon{"id": "..."}responde204. Un miembro solo puede eliminar sus propias claves; el id de otra persona responde 404. El propietario del espacio y el administrador de la instancia pueden eliminar cualquier clave del espacio activo. Esa excepción nunca cruza espacios: el propietario de otro espacio recibe 404 para las claves que no son suyas.
Inicio de sesión
La alternativa es el token de sesión de la aplicación, un valor firmado con
HMAC que el servidor emite al iniciar sesión. Se acepta en los RPC y en los
endpoints /auth/* y /tenants/*. Con la autenticación por contraseña
habilitada, un script obtiene uno con:
curl -s -X POST https://bees.example.com/auth/signin \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"..."}'
La respuesta JSON contiene token; el mismo valor se establece también como
cookie obh_session. El token expira tras BEEHIVE_SESSION_TTL.
El token lleva el espacio activo de la cuenta. GET /auth/me lista los
espacios a los que perteneces (tenants) y el activo (active_org);
POST /auth/switch con {"org_id": "..."} devuelve un nuevo token para
otro espacio.
Con BEEHIVE_DEMO=true, las sesiones de demostración son de solo lectura: la
cuenta de demostración solo puede llamar a los RPC cuyo nombre empiece por
Get, List, Pull o Subscribe. Cualquier otro RPC devuelve
permission_denied.
Consulta Autenticación para saber cómo configurar los métodos de inicio de sesión.
Páginas de protocolo
- REST / HTTP + JSON: ejemplos con curl, la forma del JSON y el contrato de paginación.
- gRPC: clientes generados y la llamada de streaming
Subscribe. - Rastreadores automáticos: publicar lecturas de básculas de colmena y de clima desde un script o dispositivo.