# b0esche.cloud API Reference Base URL: `https://go.b0esche.cloud` ## Authentication All authenticated endpoints require a JWT token in the Authorization header: ``` Authorization: Bearer ``` --- ## Health Check ### GET /health Check if the API is running. **Response:** ```json { "status": "ok", "timestamp": "2026-01-13T19:00:00Z" } ``` --- ## Authentication Endpoints ### Passkey Registration #### POST /auth/passkey/register/start Start passkey registration for a new user. **Request Body:** ```json { "username": "johndoe" } ``` **Response:** ```json { "publicKey": { "challenge": "base64-encoded-challenge", "rp": { "name": "b0esche.cloud", "id": "www.b0esche.cloud" }, "user": { "id": "base64-user-id", "name": "johndoe", "displayName": "johndoe" }, "pubKeyCredParams": [...], "timeout": 300000, "attestation": "none" } } ``` #### POST /auth/passkey/register/verify Complete passkey registration. **Request Body:** ```json { "username": "johndoe", "credential": { "id": "credential-id", "rawId": "base64-raw-id", "type": "public-key", "response": { "clientDataJSON": "base64-client-data", "attestationObject": "base64-attestation" } } } ``` **Response:** ```json { "user": { "id": "uuid", "username": "johndoe" }, "token": "jwt-token" } ``` ### Passkey Login #### POST /auth/passkey/login/start Start passkey authentication. **Request Body:** ```json { "username": "johndoe" } ``` **Response:** ```json { "publicKey": { "challenge": "base64-challenge", "timeout": 300000, "rpId": "www.b0esche.cloud", "allowCredentials": [...] } } ``` #### POST /auth/passkey/login/verify Complete passkey authentication. **Request Body:** ```json { "username": "johndoe", "credential": { "id": "credential-id", "rawId": "base64-raw-id", "type": "public-key", "response": { "clientDataJSON": "base64-client-data", "authenticatorData": "base64-auth-data", "signature": "base64-signature" } } } ``` **Response:** ```json { "user": { "id": "uuid", "username": "johndoe", "role": "user" }, "token": "jwt-token" } ``` ### Device Management #### GET /auth/passkey/devices List user's registered passkeys. **Response:** ```json { "devices": [ { "id": "uuid", "credentialId": "credential-id", "deviceLabel": "MacBook Pro", "createdAt": "2026-01-01T00:00:00Z", "lastUsedAt": "2026-01-13T19:00:00Z", "backupEligible": true } ] } ``` #### POST /auth/passkey/devices/add Add a new passkey to existing account. #### DELETE /auth/passkey/devices/{passkeyId} Remove a passkey from account. ### Recovery Codes #### POST /auth/recovery/codes/generate Generate new recovery codes (invalidates old ones). **Response:** ```json { "codes": [ "XXXX-XXXX-XXXX", "YYYY-YYYY-YYYY", ... ], "expiresAt": "2027-01-13T00:00:00Z" } ``` #### POST /auth/recovery/codes/use Use a recovery code to authenticate. **Request Body:** ```json { "username": "johndoe", "code": "XXXX-XXXX-XXXX" } ``` ### Password (Optional Fallback) #### POST /auth/password/add Add password to account. **Request Body:** ```json { "password": "secure-password" } ``` #### DELETE /auth/password/remove Remove password from account. --- ## User Endpoints ### GET /api/me Get current user profile. **Response:** ```json { "id": "uuid", "username": "johndoe", "email": "john@example.com", "displayName": "John Doe", "role": "user", "createdAt": "2026-01-01T00:00:00Z" } ``` ### PATCH /api/me Update user profile. **Request Body:** ```json { "displayName": "John D.", "email": "newemail@example.com" } ``` --- ## Organization Endpoints ### GET /api/organizations List user's organizations. **Response:** ```json { "organizations": [ { "id": "uuid", "name": "My Team", "slug": "my-team", "role": "owner", "memberCount": 5, "createdAt": "2026-01-01T00:00:00Z" } ] } ``` ### POST /api/organizations Create a new organization. **Request Body:** ```json { "name": "My New Team", "slug": "my-new-team" } ``` ### GET /api/organizations/{orgId} Get organization details. ### PATCH /api/organizations/{orgId} Update organization. ### DELETE /api/organizations/{orgId} Delete organization (owner only). ### GET /api/organizations/{orgId}/members List organization members. **Response:** ```json { "members": [ { "id": "uuid", "userId": "user-uuid", "username": "johndoe", "displayName": "John Doe", "role": "owner", "joinedAt": "2026-01-01T00:00:00Z" } ] } ``` ### POST /api/organizations/{orgId}/members Add member to organization. **Request Body:** ```json { "userId": "user-uuid", "role": "member" } ``` ### PATCH /api/organizations/{orgId}/members/{memberId} Update member role. ### DELETE /api/organizations/{orgId}/members/{memberId} Remove member from organization. --- ## File Endpoints ### GET /api/files List files in a directory. **Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `path` | string | Directory path (default: `/`) | | `orgId` | string | Organization ID (optional) | **Response:** ```json { "files": [ { "id": "uuid", "name": "document.pdf", "path": "/documents/document.pdf", "type": "file", "mimeType": "application/pdf", "size": 1048576, "createdAt": "2026-01-01T00:00:00Z", "modifiedAt": "2026-01-13T19:00:00Z" }, { "id": "uuid", "name": "photos", "path": "/photos", "type": "folder", "createdAt": "2026-01-01T00:00:00Z" } ] } ``` ### POST /api/files/upload Upload a file. **Request:** `multipart/form-data` | Field | Type | Description | |-------|------|-------------| | `file` | file | The file to upload | | `path` | string | Destination path | | `orgId` | string | Organization ID (optional) | **Response:** ```json { "file": { "id": "uuid", "name": "uploaded-file.pdf", "path": "/documents/uploaded-file.pdf", "size": 1048576 } } ``` ### GET /api/files/download Download a file. **Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `path` | string | File path | | `orgId` | string | Organization ID (optional) | **Response:** File binary with appropriate Content-Type header. ### POST /api/files/folder Create a folder. **Request Body:** ```json { "path": "/new-folder", "orgId": "org-uuid" } ``` ### DELETE /api/files Delete a file or folder. **Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `path` | string | Path to delete | | `orgId` | string | Organization ID (optional) | ### POST /api/files/move Move/rename a file or folder. **Request Body:** ```json { "sourcePath": "/old-name.pdf", "destinationPath": "/new-name.pdf", "orgId": "org-uuid" } ``` ### POST /api/files/copy Copy a file or folder. **Request Body:** ```json { "sourcePath": "/original.pdf", "destinationPath": "/copy.pdf", "orgId": "org-uuid" } ``` --- ## Admin Endpoints *Requires admin or superadmin role.* ### GET /api/admin/users List all users. **Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `page` | int | Page number (default: 1) | | `limit` | int | Items per page (default: 50) | | `search` | string | Search by username/email | ### GET /api/admin/users/{userId} Get user details. ### PATCH /api/admin/users/{userId} Update user (role, status). ### DELETE /api/admin/users/{userId} Delete user account. ### Admin Invitations #### GET /auth/admin/invitations List admin invitations. #### POST /auth/admin/invitations Create admin invitation. **Request Body:** ```json { "username": "newadmin", "roleId": "admin-role-uuid", "expiresIn": 86400 } ``` **Response:** ```json { "invitation": { "id": "uuid", "token": "invite-token", "expiresAt": "2026-01-14T19:00:00Z" } } ``` #### POST /auth/admin/invitations/{token}/accept Accept an admin invitation. #### DELETE /auth/admin/invitations/{token} Revoke an invitation. --- ## Activity Endpoints ### GET /api/activities Get activity log. **Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `page` | int | Page number | | `limit` | int | Items per page | | `orgId` | string | Filter by organization | | `userId` | string | Filter by user | | `action` | string | Filter by action type | **Response:** ```json { "activities": [ { "id": "uuid", "userId": "user-uuid", "username": "johndoe", "action": "file.upload", "resourceType": "file", "resourceId": "/documents/report.pdf", "metadata": { "size": 1048576 }, "createdAt": "2026-01-13T19:00:00Z" } ], "pagination": { "page": 1, "limit": 50, "total": 150 } } ``` --- ## Error Responses All errors follow this format: ```json { "error": { "code": "ERROR_CODE", "message": "Human-readable error message", "details": {} } } ``` ### Common Error Codes | Code | HTTP Status | Description | |------|-------------|-------------| | `UNAUTHORIZED` | 401 | Missing or invalid token | | `FORBIDDEN` | 403 | Insufficient permissions | | `NOT_FOUND` | 404 | Resource not found | | `VALIDATION_ERROR` | 400 | Invalid request data | | `CONFLICT` | 409 | Resource already exists | | `INTERNAL_ERROR` | 500 | Server error | --- ## Rate Limiting - **Authentication endpoints**: 10 requests/minute - **API endpoints**: 100 requests/minute - **File uploads**: 50 requests/hour Rate limit headers: ``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 1705172400 ``` --- ## Webhooks (Future) Planned webhook events: - `user.created` - `user.deleted` - `file.uploaded` - `file.deleted` - `org.member.added` - `org.member.removed`