Appearance
API Reference
The Hub API is a Fastify HTTP server. All endpoints are under /api/.
Authentication
| Method | Description |
|---|---|
| JWT Cookie | Set by POST /api/auth/login, sent automatically by browsers |
| Bearer Token | Authorization: Bearer <token> for mobile apps and API clients |
Both resolve to a user identity with tenant role. Platform admins have cross-tenant access.
Auth
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /auth/register | Public* | Register user (with optional invite token) |
| POST | /auth/login | Public | Login, returns JWT cookie (+ token if ?returnToken=true) |
| POST | /auth/logout | Authenticated | Clear session |
| GET | /auth/me | Authenticated | Current user, tenants, preferences |
| PUT | /auth/me/preferences | Authenticated | Update language preferences |
| POST | /auth/invites | Admin+ | Generate invite link (tenant + role) |
| GET | /auth/invites | Admin+ | List pending invites |
| DELETE | /auth/invites/:id | Admin+ | Revoke invite |
| GET | /auth/members | Admin+ | List tenant members (excludes platform admins) |
| POST | /auth/create-tenant | Logged in* | Create new tenant |
*Gated by platform settings (allow_self_registration, allow_tenant_creation)
Detections
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /detections | Viewer+ | List detections (filterable) |
| GET | /detections/:id | Viewer+ | Detection detail with storage key |
| GET | /detections/votes | Viewer+ | Get user's votes for detection IDs |
| POST | /detections/:id/verify | Member+ | Submit verification vote |
Query params for GET /detections:
tenantId— filter by tenantsatelliteId— filter by satellitespecies— filter by species codeminConfidence— minimum confidence thresholdverificationStatus—pending_review,confirmed,rejected,unverifiedlimit,offset— pagination
Satellites
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /satellites | Viewer+ | List satellites with latest telemetry |
| GET | /satellites/:id | Viewer+ | Satellite detail |
| POST | /satellites | Admin+ | Register satellite (returns MQTT credentials) |
| PATCH | /satellites/:id | Member+ | Update satellite (rename) |
| POST | /satellites/:id/profile | Admin+ | Push recording profile via MQTT |
| GET | /satellites/:id/schedule | Viewer+ | Resolved recording schedule with sun times |
| DELETE | /satellites/:id | Admin+ | Delete satellite (revokes MQTT) |
Audio
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /audio/:chunkId | Viewer+ | Stream audio WAV from MinIO |
Alerts
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /alerts | Viewer+ | List alerts (?acknowledged=true/false) |
| POST | /alerts/:id/acknowledge | Viewer+ | Dismiss alert |
Export
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /export/detections | Member+ | Export CSV or JSON (?format=csv/json) |
| GET | /export/ebird | Member+ | eBird checklist format |
| GET | /export/inaturalist | Member+ | iNaturalist observation format |
| GET | /export/xenocanto | Member+ | xeno-canto submission format |
Stats
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /stats/dashboard | Viewer+ | Species count, detection count, chunk count |
| GET | /stats/trends | Viewer+ | Daily detection trends (?days=30) |
| GET | /stats/top-species | Viewer+ | Top species ranking |
| GET | /stats/activity | Viewer+ | Hourly detection activity |
| GET | /stats/verification | Viewer+ | Verification progress counts |
| GET | /stats/leaderboard | Viewer+ | Verification contributor ranking |
Species
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /species/languages | Public | Available translation languages |
| GET | /species/translate | Viewer+ | Translate single species |
| POST | /species/translate | Viewer+ | Bulk translate species names |
| POST | /species/images | Viewer+ | Get image statuses (queues missing) |
| GET | /species/image/proxy | Viewer+ | Serve species image from MinIO |
| GET | /species/image-cache/stats | Platform Admin | Image cache statistics |
| POST | /species/image-cache/clear | Platform Admin | Clear entire image cache |
| POST | /species/image-cache/retry | Platform Admin | Re-queue failed downloads |
Webhooks
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /webhooks | Admin+ | List webhooks for tenant |
| POST | /webhooks | Admin+ | Create webhook |
| DELETE | /webhooks/:id | Admin+ | Delete webhook |
| POST | /webhooks/:id/test | Admin+ | Send test payload |
Webhook payload: Detection details with HMAC signature in X-Webhook-Signature header. Event types: detection.new, detection.rare, satellite.offline
Workers
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /workers | Admin+ | Queue stats + connected workers |
| GET | /workers/jobs | Admin+ | Recent completed jobs |
Settings
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /settings/tenant | Viewer+ | Tenant settings |
| PUT | /settings/tenant | Admin+ | Update tenant settings |
| GET | /settings/platform | Platform Admin | Platform settings |
| PUT | /settings/platform | Platform Admin | Update platform settings |
Tenants
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /tenants | Authenticated | List tenants |
Admin (Platform Admin only)
| Method | Path | Description |
|---|---|---|
| GET | /admin/users | List all users (with search) |
| GET | /admin/users/:id | User detail |
| PUT | /admin/users/:id | Update user (name, email, admin flag) |
| POST | /admin/users/:id/block | Block/unblock user |
| POST | /admin/users/:id/reset-password | Reset password |
| DELETE | /admin/users/:id | Delete user |
| POST | /admin/users/:id/tenants | Add user to tenant (409 if already member) |
| DELETE | /admin/users/:id/tenants/:tid | Remove from tenant |
| PUT | /admin/members/:id/role | Change member role |
| DELETE | /admin/members/:id | Remove member from tenant |
WebSocket
Connect to /ws/events?tenantId=<id> for real-time events.
Event types:
detection— new bird detected (species, confidence, satellite, rare flag)alert— system alert (rare species, satellite offline, etc.)
Toast format: Rare species notifications show translated names (primary + secondary languages).
Health
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /health | Public | Returns { status: "ok" } |