L'API Openbeehive
Le serveur expose une API Connect-RPC définie en
Protocol Buffers sous
proto/openbeehive/v1.
Chaque RPC est accessible en HTTP/JSON simple, en gRPC et en gRPC-Web depuis la
même URL. L'application elle-même n'utilise que SyncService ; les autres
services existent pour les scripts, les capteurs et les intégrations.
URL de base et forme du chemin
L'API est servie par le même processus que l'application, sur la même origine :
POST <origin>/openbeehive.v1.<Service>/<Method>
Par exemple https://app.openbeehive.org/openbeehive.v1.ApiaryService/ListApiaries
sur le service hébergé, ou votre propre origine en auto-hébergement.
Services servis
Dix services sont enregistrés sur le serveur (server/cmd/server/main.go) :
| Service | 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 (flux serveur) |
Chaque RPC est limité à l'espace (tenant) actif de l'appelant. Les ids d'un
autre espace se comportent comme des ids inconnus (not_found).
Les écritures passent par la synchronisation
Chaque RPC d'écriture (Create*, Update*, Delete*, RelocateHive,
SetTaskDone, AddInspectionPhoto, RemoveInspectionPhoto) est appliqué
avec la même fusion champ par champ et ajouté au même journal des changements
que SyncService.Push. Une ligne écrite via l'API atteint chaque appareil à sa
prochaine synchronisation, et une modification ultérieure depuis un appareil
fusionne avec elle champ par champ, exactement comme les modifications de deux
appareils fusionnent entre elles. Les suppressions sont douces : la ligne reçoit
un tombstone (deleted = 1) et disparaît des listes et de l'application.
Les écritures côté serveur reproduisent les flux propres à l'application
(server/internal/service/writer.go est un portage de
app/src/lib/local/history.ts), de sorte que l'historique affiché par un
appareil est le même qu'un enregistrement ait été saisi dans l'application ou
via l'API :
CreateHiveécrit la ruche, ouvre un intervalle de placement et enregistre un événementCREATED. Les nouvelles ruches démarrent enHIVE_STATUS_ACTIVE.RelocateHiveclôture le placement ouvert, en ouvre un nouveau sur le rucher cible et enregistre un événementMOVED.UpdateHivene déplace jamais une ruche.CreateQueenmet fin au règne de la reine active de la ruche (active = false,replacedAtpositionné sur l'introducedAtde la nouvelle reine), enregistre les événementsQUEEN_REPLACEDetQUEEN_INTRODUCED, et déduit la couleur de marquage deyearlorsque vous n'en envoyez aucune.CreateInspectionetCreateTreatmentfigent le rucher et la reine régnante à ladatede l'enregistrement (un enregistrement antidaté est résolu à partir de l'historique des placements et des reines) et enregistrent un événementINSPECTIONouTREATMENT.CreateHarvestfige de la même façon le rucher et la reine régnante à ladate, écrit la ligne de récolte et enregistre un événementHARVESTqui porteamountKget le titre<kg> kg <variety>(Honeylorsquevarietyest vide).GetDashboardetGetHoneyStatsadditionnent ces événements, de sorte qu'une récolte envoyée via l'API compte immédiatement dans les chiffres de miel.amountKgdoit être supérieur à0.- Une tâche avec un
hiveIdou unapiaryIdse synchronise sous ce rucher et est partagée avec toutes les personnes qui le voient ; une tâche sans l'un ni l'autre vit dans le scope personnel de l'appelant et n'atteint que les appareils de cet utilisateur.
Les lectures (Get*, List*, ListEvents, GetDashboard, GetHoneyStats)
interrogent directement les tables du serveur. Elles montrent immédiatement les
écritures faites via l'API, et les écritures des appareils dès que l'appareil
les a poussées.
Pas encore dans l'API
- Pas de RPC de modification de récolte.
HarvestServicen'a queCreateHarvest,ListHarvestsetDeleteHarvest. Pour corriger une récolte, supprimez-la et recréez-la, ou modifiez-la dans l'application. - Pas de RPC de placement. Les placements sont écrits par
CreateHiveetRelocateHiveet n'apparaissent que dans le flux de synchronisation. EventServiceest en lecture seule. Les événements sont écrits par les flux ci-dessus et par l'application.
Voir le protocole de synchronisation pour le format des changements et le modèle de données pour les colonnes derrière chaque message.
Endpoints hors RPC
Quelques endpoints HTTP simples se trouvent à côté des services RPC :
| Chemin | Rôle |
|---|---|
GET /healthz | Renvoie ok |
GET /files/<key> | Fichiers stockés, uniquement avec le backend de blobs sur système de fichiers (BEEHIVE_BLOB_BACKEND=fs) |
POST /auth/signin, POST /auth/signup, GET /auth/verify | Comptes e-mail/mot de passe (BEEHIVE_PASSWORD_AUTH=true) |
GET /auth/login, GET /auth/callback | OIDC (BEEHIVE_OIDC_PROVIDERS défini) |
/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 | Utilitaires de session et d'espace (tenant), présents dès qu'une méthode de connexion est activée |
GET /auth/api-keys, POST /auth/api-keys, POST /auth/api-keys/delete | Gestion des clés API (lister, créer, supprimer), présente dès qu'une méthode de connexion est activée ; session uniquement, une clé ne peut pas les appeler |
/tenants/create, /tenants/invite, /tenants/invites, /tenants/invite/revoke, /tenants/delete | Administration des espaces, présente dès qu'une méthode de connexion est activée |
POST /auth/demo-login | Uniquement avec BEEHIVE_DEMO=true |
Ils sont utilisés par les écrans de connexion et de paramètres de l'application. Ils ne font pas partie du contrat proto.
Authentification
La façon dont une requête est authentifiée dépend de la présence d'une méthode de connexion sur l'instance :
- Aucune connexion configurée (auto-hébergé,
BEEHIVE_PASSWORD_AUTH=false,BEEHIVE_OIDC_PROVIDERSvide,BEEHIVE_WEBAUTHN_ENABLED=false) : chaque requête s'exécute en tant qu'utilisateur local fixe. N'envoyez aucun identifiant. Il n'y a pas de clés API sur une telle instance ; aucune n'est nécessaire. - Connexion configurée : chaque RPC a besoin d'une clé API ou d'un jeton de
session dans
Authorization: Bearer <token>(le cookieobh_sessionest accepté pour les jetons de session). Une requête sans jeton valide reçoit le code Connectunauthenticated(HTTP 401).
Clés API
Une clé API est l'identifiant recommandé pour les scripts, les capteurs et les intégrations. Les clés se gèrent dans l'application sous Paramètres → Clés API (voir Comptes et espaces) :
- Connectez-vous, basculez vers l'espace dans lequel le script doit écrire et ouvrez Paramètres → Clés API.
- Saisissez un nom (par exemple
hive scale), choisissez les permissions (Lecture et écriture ou Lecture seule) et une expiration (N'expire jamais, 30 jours, 90 jours ou 1 an), puis touchez Créer une clé. La clé commence parobhk_et n'est affichée qu'une seule fois ; copiez-la maintenant. Le serveur ne stocke que son hachage SHA-256 et les 12 premiers caractères pour l'affichage. - Envoyez-la à chaque RPC :
Authorization: Bearer obhk_...
Ce qu'une clé peut et ne peut pas faire :
- Elle agit en tant que son propriétaire, avec le rôle de celui-ci, dans l'espace qui était actif lors de sa création. Elle ne peut pas changer d'espace ; créez une clé par espace si un script en a besoin de plusieurs.
- Elle ne fonctionne que sur les RPC. Les endpoints
/auth/*et/tenants/*, y compris la gestion des clés elle-même, exigent une vraie session : une clé ne peut ni lister, ni créer, ni supprimer de clés. - Elle a l'une de deux portées, fixée à la création. Une clé
write(la valeur par défaut) peut appeler tous les RPC que son propriétaire peut appeler. Une cléreadne peut appeler que les RPC dont le nom commence parGet,List,PullouSubscribe; tout autre RPC renvoie le code Connectpermission_denied(HTTP 403) avec le messagethis API key is read-only. - Elle n'expire que si vous définissez une expiration :
expires_in_daysde0(jamais, la valeur par défaut) à3650. Passéexpires_at, chaque RPC renvoieunauthenticated(HTTP 401) avec le messageAPI key expired. Les clés expirées restent dans la liste jusqu'à ce que vous les supprimiez. - Elle cesse de fonctionner dès qu'elle est supprimée dans les Paramètres, et elle disparaît avec l'appartenance : lorsque son propriétaire quitte l'espace ou en est retiré, la clé est refusée.
- Chaque utilisation met à jour
last_used_at, affiché comme Dernière utilisation dans les Paramètres. - Le compte de démonstration ne peut pas créer de clés.
Les mêmes endpoints que ceux de l'application sont ouverts à un script authentifié par session :
GET /auth/api-keysrenvoie{"keys": [{id, name, prefix, scope, created_at, expires_at, last_used_at, mine}]}, vos propres clés dans l'espace actif uniquement.scopevaut"write"ou"read";expires_atetlast_used_atsont des horodatages RFC 3339 ounull;minevaut toujourstrueici.GET /auth/api-keys?tenant=1renvoie toutes les clés de l'espace actif, chaque ligne portant en plususer_id,user_emailet un indicateurminequi vauttruesur vos propres clés. Seuls le propriétaire de l'espace (le rôle que l'application appelle Admin) et l'administrateur de l'instance peuvent l'appeler ; tout le monde d'autre reçoit HTTP 403.POST /auth/api-keysavec{"name": "...", "scope": "write", "expires_in_days": 0}renvoie{id, name, prefix, scope, created_at, expires_at, token}.scopevaut"write"etexpires_in_daysvaut0(jamais) par défaut lorsqu'ils sont omis. Toute autre portée, ou une durée de vie inférieure à0ou supérieure à3650, répond HTTP 400.POST /auth/api-keys/deleteavec{"id": "..."}répond204. Un membre ne peut supprimer que ses propres clés ; l'id d'une clé de quelqu'un d'autre répond 404. Le propriétaire de l'espace et l'administrateur de l'instance peuvent supprimer n'importe quelle clé de l'espace actif. Cette dérogation ne franchit jamais les espaces : le propriétaire d'un autre espace reçoit 404 pour les clés qui ne sont pas les siennes.
Connexion par session
L'alternative est le jeton de session de l'application, une valeur signée en
HMAC que le serveur émet à la connexion. Il est accepté sur les RPC et sur les
endpoints /auth/* et /tenants/*. Avec l'authentification par mot de passe
activée, un script en obtient un avec :
curl -s -X POST https://bees.example.com/auth/signin \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"..."}'
La réponse JSON contient token ; la même valeur est aussi définie dans le
cookie obh_session. Le jeton expire après BEEHIVE_SESSION_TTL.
Le jeton porte l'espace actif du compte. GET /auth/me liste les espaces
auxquels vous appartenez (tenants) et l'espace actif (active_org) ;
POST /auth/switch avec {"org_id": "..."} renvoie un nouveau token pour
un autre espace.
Avec BEEHIVE_DEMO=true, les sessions de démonstration sont en lecture seule :
le compte de démonstration ne peut appeler que les RPC dont le nom commence par
Get, List, Pull ou Subscribe. Tout autre RPC renvoie
permission_denied.
Voir Authentification pour configurer les méthodes de connexion.
Pages par protocole
- REST / HTTP + JSON : exemples curl, forme du JSON et contrat de pagination.
- gRPC : clients générés et l'appel
Subscribeen streaming. - Trackers automatisés : envoyer les relevés d'une balance de ruche ou d'un capteur climatique depuis un script ou un appareil.