-
Notifications
You must be signed in to change notification settings - Fork 9
API Reference
MiBee NVR uses HTTP Basic Authentication for protected endpoints. The authentication credentials are configured in the application settings.
curl -u username:password http://localhost:9090/api/cameras- If
password_hashis configured in the settings: All protected endpoints require valid Basic Auth credentials - If
password_hashis empty in settings: Authentication is bypassed (no protection) - Failed authentication returns
401 Unauthorizedwith empty body
Endpoint: GET /api/health
Get overall system health status including database and storage disk space.
Request:
curl http://localhost:9090/api/healthResponse:
{
"status": "ok",
"checks": {
"database": {
"status": "ok",
"message": ""
},
"storage": {
"status": "ok",
"message": ""
}
},
"uptime": "2h34m15s"
}Endpoint: GET /api/readyz
Check if the system is ready to accept requests (same as health check).
Request:
curl http://localhost:9090/api/readyzResponse:
{
"status": "ok"
}Endpoint: GET /api/stats/system
Get detailed system statistics including CPU, memory, and network usage.
Request:
curl -u username:password \
"http://localhost:9090/api/stats/system"Response:
{
"cpu": {
"total": 1234567,
"idle": 987654
},
"memory": {
"total": 1073741824,
"available": 536870912,
"process_rss": 10485760
},
"network": {
"bytes_sent": 1048576,
"bytes_recv": 2097152
},
"uptime": "2h34m15s",
"timestamp": 1716789012
}Endpoint: GET /api/cameras
Get a list of all configured cameras.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras"Response:
[
{
"id": "front-door",
"name": "Front Door",
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"enabled": true,
"status": "recording",
"last_seen": "2024-01-01T10:15:00Z",
"retention_days": 30,
"username": "admin",
"has_password": true,
"sub_stream_url": "",
"snapshot_url": "",
"sample_interval": 1,
"hls_max_fps": 30,
"did": "",
"vendor": ""
}
]Endpoint: POST /api/cameras
Add a new camera configuration.
Request Body:
{
"name": "Front Door",
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"username": "admin",
"password": "secret",
"enabled": true,
"retention_days": 30,
"sub_stream_url": "rtsp://192.168.1.100:554/sub_stream",
"snapshot_url": "http://192.168.1.100:8080/snapshot",
"sample_interval": 1,
"hls_max_fps": 30
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"name": "Front Door",
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"username": "admin",
"password": "secret",
"enabled": true
}' \
"http://localhost:9090/api/cameras"Response (201 Created):
{
"id": "front-door",
"name": "Front Door",
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"enabled": true
}Endpoint: GET /api/cameras/:id
Get a specific camera configuration.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/front-door"Response:
{
"id": "front-door",
"name": "Front Door",
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"enabled": true,
"status": "recording",
"last_seen": "2024-01-01T10:15:00Z"
}Endpoint: PUT /api/cameras/:id
Update camera configuration. All fields are optional for partial updates.
Request Body:
{
"name": "Updated Front Door",
"url": "rtsp://192.168.1.100:554/new_stream",
"enabled": false,
"retention_days": 7
}Request:
curl -u username:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Front Door",
"url": "rtsp://192.168.1.100:554/new_stream",
"enabled": false
}' \
"http://localhost:9090/api/cameras/front-door"Response:
{
"id": "front-door",
"name": "Updated Front Door",
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/new_stream",
"enabled": false
}Endpoint: DELETE /api/cameras/:id
Delete a camera configuration.
Request:
curl -u username:password \
-X DELETE \
"http://localhost:9090/api/cameras/backyard"Response:
{
"status": "deleted"
}Endpoint: POST /api/cameras/test-connection
Test camera connection with provided configuration.
Request Body:
{
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"username": "admin",
"password": "secret"
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"username": "admin",
"password": "secret"
}' \
"http://localhost:9090/api/cameras/test-connection"Response:
{
"success": true,
"message": "Connection successful",
"details": {
"protocol": "rtsp",
"encoding": "h264",
"latency_ms": 45,
"frames_received": 10
}
}Endpoint: POST /api/cameras/:id/start
Start recording for a camera.
Request:
curl -u username:password \
-X POST \
"http://localhost:9090/api/cameras/front-door/start"Response:
{
"status": "started"
}Endpoint: POST /api/cameras/:id/stop
Stop recording for a camera.
Request:
curl -u username:password \
-X POST \
"http://localhost:9090/api/cameras/front-door/stop"Response:
{
"status": "stopped"
}Endpoint: GET /api/cameras/{id}/snapshot
Get a JPEG snapshot image from a camera.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/front-door/snapshot" \
-o snapshot.jpgResponse: JPEG image with Content-Type: image/jpeg and Cache-Control: max-age=5
Endpoint: GET /api/cameras/:id/stream/*path
Provide on-demand HLS live streaming.
Request (HLS playlist):
curl -u username:password \
"http://localhost:9090/api/cameras/front-door/stream/stream.m3u8"Request (HLS segment):
curl -u username:password \
"http://localhost:9090/api/cameras/front-door/stream/segment_001.ts"Response: HLS playlist or segment file content
Endpoint: GET /api/cameras/{id}/onvif/profiles
Get available media profiles for an ONVIF camera.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/onvif/profiles"Response:
{
"profiles": [
{
"token": "profile_1",
"name": "Profile 1",
"encoding": "H264",
"width": 1920,
"height": 1080
},
{
"token": "profile_2",
"name": "Profile 2",
"encoding": "H264",
"width": 1280,
"height": 720
}
],
"capabilities": {
"ptz": true,
"streaming": true
}
}Endpoint: GET /api/cameras/{id}/onvif/capabilities
Get detailed device capabilities for an ONVIF camera.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/onvif/capabilities"Response:
{
"ptz": true,
"imaging": true,
"events": false,
"snapshot": true,
"streaming": true,
"device": true
}Endpoint: GET /api/cameras/:id/onvif/profiles
Get available media profiles for an ONVIF camera.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/onvif/profiles"Response:
{
"profiles": [
{
"token": "profile_1",
"name": "Profile 1",
"video_encoder": "H264",
"audio_encoder": "G.711"
}
]
}Endpoint: POST /api/cameras/:id/ptz/move
Move PTZ camera.
Request Body:
{
"x": 0.5,
"y": 0.5,
"zoom": 1.0,
"speed": 1.0
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"x": 0.5,
"y": 0.5,
"zoom": 1.0
}' \
"http://localhost:9090/api/cameras/lobby/ptz/move"Response:
{
"status": "moving"
}Endpoint: GET /api/cameras/{id}/ptz/presets
Get saved PTZ presets for an ONVIF camera.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/ptz/presets"Response:
{
"presets": [
{
"token": "preset_1",
"name": "Home Position",
"position": {
"pan": 0.0,
"tilt": 0.0,
"zoom": 1.0
}
},
{
"token": "preset_2",
"name": "Corner View",
"position": {
"pan": 0.5,
"tilt": 0.3,
"zoom": 1.5
}
}
]
}Endpoint: POST /api/cameras/{id}/ptz/presets
Create a new PTZ preset.
Request Body:
{
"name": "Home Position"
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"name": "Home Position"
}' \
"http://localhost:9090/api/cameras/lobby/ptz/presets"Response:
{
"token": "preset_123"
}Endpoint: POST /api/cameras/{id}/ptz/presets/{token}/goto
Move camera to a saved PTZ preset.
Request:
curl -u username:password \
-X POST \
"http://localhost:9090/api/cameras/lobby/ptz/presets/preset_123/goto"Response:
{
"status": "ok"
}Endpoint: DELETE /api/cameras/{id}/ptz/presets/{token}
Delete a PTZ preset.
Request:
curl -u username:password \
-X DELETE \
"http://localhost:9090/api/cameras/lobby/ptz/presets/preset_123"Response:
{
"status": "ok"
}Endpoint: POST /api/cameras/{id}/ptz/move
Move PTZ camera with absolute/relative positioning.
Request Body:
{
"mode": "absolute",
"pan": 0.5,
"tilt": 0.3,
"zoom": 1.0,
"speed": 1.0
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"mode": "absolute",
"pan": 0.5,
"tilt": 0.3,
"zoom": 1.0
}' \
"http://localhost:9090/api/cameras/lobby/ptz/move"Response:
{
"status": "moving"
}Endpoint: POST /api/cameras/{id}/ptz/stop
Stop PTZ movement.
Request:
curl -u username:password \
-X POST \
"http://localhost:9090/api/cameras/lobby/ptz/stop"Response:
{
"status": "stopped"
}Endpoint: GET /api/cameras/{id}/ptz/status
Get current PTZ position and movement status.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/ptz/status"Response:
{
"pan": 0.5,
"tilt": 0.3,
"zoom": 1.0,
"moving": false
}
#### Imaging Settings
**Endpoint:** `GET /api/cameras/{id}/imaging/settings`
Get current imaging settings for an ONVIF camera.
**Request:**
```bash
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/imaging/settings"Response:
{
"brightness": 0.5,
"contrast": 0.7,
"saturation": 0.6,
"sharpness": 0.8,
"exposure": {
"mode": "auto",
"exposure_time": 0.0,
"gain": 1.0
},
"white_balance": {
"mode": "auto",
"color_temperature": 0.0
}
}Endpoint: PUT /api/cameras/{id}/imaging/settings
Update imaging parameters for an ONVIF camera.
Request Body:
{
"brightness": 0.6,
"contrast": 0.8,
"saturation": 0.7,
"sharpness": 0.9,
"exposure": {
"mode": "manual",
"exposure_time": 0.02,
"gain": 1.2
},
"white_balance": {
"mode": "manual",
"color_temperature": 4500
}
}Request:
curl -u username:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"brightness": 0.6,
"contrast": 0.8,
"exposure": {
"mode": "manual",
"exposure_time": 0.02
}
}' \
"http://localhost:9090/api/cameras/lobby/imaging/settings"Response:
{
"status": "ok"
}Endpoint: GET /api/cameras/{id}/imaging/options
Get supported imaging parameter ranges for an ONVIF camera.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/imaging/options"Response:
{
"brightness": {
"min": 0.0,
"max": 1.0
},
"contrast": {
"min": 0.0,
"max": 1.0
},
"saturation": {
"min": 0.0,
"max": 1.0
},
"exposure": {
"modes": ["auto", "manual"],
"exposure_time": {
"min": 0.001,
"max": 0.1
},
"gain": {
"min": 1.0,
"max": 10.0
}
},
"white_balance": {
"modes": ["auto", "manual"],
"color_temperature": {
"min": 2000,
"max": 8000
}
}
}Endpoint: GET /api/cameras/{id}/snapshot/uri
Get the snapshot URI for an ONVIF camera.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/snapshot/uri"Response:
{
"uri": "http://192.168.1.100:8080/snapshot.jpg"
}Endpoint: POST /api/cameras/:id/ptz/stop
Stop PTZ movement.
Request:
curl -u username:password \
-X POST \
"http://localhost:9090/api/cameras/lobby/ptz/stop"Response:
{
"status": "stopped"
}Endpoint: GET /api/cameras/:id/ptz/status
Get current PTZ position.
Request:
curl -u username:password \
"http://localhost:9090/api/cameras/lobby/ptz/status"Response:
{
"x": 0.5,
"y": 0.5,
"zoom": 1.0
}
### ONVIF API
### Device Management
#### Reboot Camera
**Endpoint:** `POST /api/cameras/{id}/onvif/reboot`
Reboot an ONVIF camera.
**Request:**
```bash
curl -u username:password \n -X POST \n "http://localhost:9090/api/cameras/lobby/onvif/reboot"Response:
{
"status": "ok"
}Note: Some cameras may not support this operation and will return 501 Not Implemented.
Endpoint: GET /api/cameras/{id}/onvif/network
Get network interface configuration from an ONVIF camera.
Request:
curl -u username:password \n "http://localhost:9090/api/cameras/lobby/onvif/network"Response:
{
"interfaces": [
{
"name": "eth0",
"enabled": true,
"ipv4": {
"enabled": true,
"dhcp": false,
"address": "192.168.1.100",
"netmask": "255.255.255.0",
"gateway": "192.168.1.1"
},
"dns": ["8.8.8.8", "8.8.4.4"]
}
]
}Endpoint: PUT /api/cameras/{id}/onvif/network
Configure network interfaces on an ONVIF camera.
Request Body:
{
"interfaces": [
{
"name": "eth0",
"enabled": true,
"ipv4": {
"enabled": true,
"dhcp": false,
"address": "192.168.1.101",
"netmask": "255.255.255.0",
"gateway": "192.168.1.1"
}
}
]
}Request:
curl -u username:password \n -X PUT \n -H "Content-Type: application/json" \n -d '{
"interfaces": [
{
"name": "eth0",
"enabled": true,
"ipv4": {
"enabled": true,
"dhcp": false,
"address": "192.168.1.101",
"netmask": "255.255.255.0",
"gateway": "192.168.1.1"
}
}
]
}' \n "http://localhost:9090/api/cameras/lobby/onvif/network"Response:
{
"status": "ok"
}Note: Camera restart may be required for network changes to take effect. Some cameras may not support this operation.
Endpoint: POST /api/onvif/discover
Discover ONVIF devices on the network.
Request Body:
{
"timeout": 5,
"target": "192.168.1.0/24"
}Request:
curl -u username:password \n -X POST \n -H "Content-Type: application/json" \n -d '{
"timeout": 5
}' \n "http://localhost:9090/api/onvif/discover"Response:
{
"devices": [
{
"uuid": "uuid-12345",
"name": "Camera 1",
"xaddrs": ["http://192.168.1.104:80/onvif/device_service"],
"scopes": ["onvif://www.onvif.org/Profile/Video"],
"hardware": "Camera Model ABC",
"endpoint": "http://192.168.1.104:80/onvif/device_service"
}
]
}Endpoint: GET /api/onvif/discover/{ip}
Get detailed information about a specific ONVIF device.
Request:
curl -u username:password \n "http://localhost:9090/api/onvif/discover/192.168.1.104"Response:
{
"device_info": {
"manufacturer": "CameraCo",
"model": "ABC-123",
"firmware": "1.2.3",
"serial_number": "CAM123456"
},
"profiles": [
{
"token": "profile_1",
"name": "Profile 1",
"encoding": "H264",
"width": 1920,
"height": 1080
}
]
}Endpoint: PUT /api/cameras/:id/merge-config
Set merge configuration overrides for a specific camera.
Request Body:
{
"enabled": true,
"check_interval": "30m",
"window_size": "1h",
"batch_limit": 150,
"min_segment_age": "5m",
"min_segments_to_merge": 2
}Request:
curl -u username:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"enabled": false,
"batch_limit": 50
}' \
"http://localhost:9090/api/cameras/front-door/merge-config"Response:
{
"status": "updated"
}Endpoint: DELETE /api/cameras/:id/merge-config
Remove per-camera merge overrides.
Request:
curl -u username:password \
-X DELETE \
"http://localhost:9090/api/cameras/front-door/merge-config"Response:
{
"status": "reset"
}Endpoint: GET /api/recordings
Retrieve a paginated list of recordings with optional filtering.
Query Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
camera_id |
string | No | Filter by camera ID | front-door |
format |
string | No | Filter by format (h264, h265, mjpeg) | h264 |
merged |
boolean | No | Filter by merge status | true |
start |
string | No | Start time (RFC3339 format) | 2024-01-01T00:00:00Z |
end |
string | No | End time (RFC3339 format) | 2024-01-02T00:00:00Z |
limit |
integer | No | Maximum results (default: 50) | 20 |
offset |
integer | No | Result offset for pagination | 0 |
Request:
curl -u username:password \
"http://localhost:9090/api/recordings?format=h264&limit=10&offset=0"Response:
{
"recordings": [
{
"id": "1704123456789012345",
"camera_id": "front-door",
"file_path": "/data/recordings/h264/front-door_1704123456789012345.mp4",
"format": "h264",
"started_at": "2024-01-01T12:34:56.789Z",
"ended_at": "2024-01-01T12:35:06.789Z",
"duration": 10.0,
"file_size": 1048576,
"frame_count": 300,
"merged": false
}
],
"total": 1
}Endpoint: GET /api/recordings/:id
Retrieve a specific recording by ID.
Request:
curl -u username:password \
"http://localhost:9090/api/recordings/1704123456789012345"Response:
{
"id": "1704123456789012345",
"camera_id": "front-door",
"file_path": "/data/recordings/h264/front-door_1704123456789012345.mp4",
"format": "h264",
"started_at": "2024-01-01T12:34:56.789Z",
"ended_at": "2024-01-01T12:35:06.789Z",
"duration": 10.0,
"file_size": 1048576,
"frame_count": 300,
"merged": false
}Endpoint: DELETE /api/recordings/:id
Delete a recording by ID.
Request:
curl -u username:password \
-X DELETE \
"http://localhost:9090/api/recordings/1704123456789012345"Response:
{
"status": "deleted"
}Endpoint: GET /api/recordings/:id/download
Download a recording file.
Query Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
frame |
integer | No | For MJPEG format, download specific frame | 150 |
Request (H264):
curl -u username:password \
-o recording.mp4 \
"http://localhost:9090/api/recordings/1704123456789012345/download"Request (MJPEG with specific frame):
curl -u username:password \
-o frame_150.jpg \
"http://localhost:9090/api/recordings/1704123456789012345/download?frame=150"Response: Binary file content (MP4 or JPEG)
Endpoint: GET /api/recordings/:id/frames
List all frames for an MJPEG recording.
Request:
curl -u username:password \
"http://localhost:9090/api/recordings/1704123456789012345/frames"Response:
{
"frames": [
{
"index": 0,
"filename": "front-door_1704123456789012345_0000.jpg",
"size": 54321
},
{
"index": 1,
"filename": "front-door_1704123456789012345_0001.jpg",
"size": 52345
}
]
}Endpoint: POST /api/recordings/batch-delete
Delete multiple recordings by ID.
Request Body:
{
"recording_ids": ["id1", "id2", "id3"]
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"recording_ids": ["1704123456789012345", "1704123456789012346"]
}' \
"http://localhost:9090/api/recordings/batch-delete"Response:
{
"deleted": 2,
"failed": 0
}Endpoint: GET /api/archives
List all archive groups by camera.
Request:
curl -u username:password \
"http://localhost:9090/api/archives"Response:
{
"archives": [
{
"camera_id": "front-door",
"retention_days": 30,
"recordings_count": 150,
"total_size_mb": 1024
}
]
}Endpoint: GET /api/archives/{cameraID}/recordings
List recordings for a specific archive.
Request:
curl -u username:password \
"http://localhost:9090/api/archives/front-door/recordings"Response:
{
"recordings": [
{
"id": "1704123456789012345",
"started_at": "2024-01-01T12:34:56.789Z",
"duration": 10.0,
"file_size": 1048576
}
],
"total": 1
}Endpoint: DELETE /api/archives/{cameraID}
Delete an entire archive group for a camera.
Request:
curl -u username:password \
-X DELETE \
"http://localhost:9090/api/archives/front-door"Response:
{
"status": "deleted"
}Endpoint: DELETE /api/archives/{cameraID}/recordings/{recordingID}
Delete a specific recording from an archive.
Request:
curl -u username:password \
-X DELETE \
"http://localhost:9090/api/archives/front-door/recordings/1704123456789012345"Response:
{
"status": "deleted"
}Endpoint: PUT /api/archives/{cameraID}/retention
Set retention period for an archive group.
Request Body:
{
"retention_days": 60
}Request:
curl -u username:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"retention_days": 60
}' \
"http://localhost:9090/api/archives/front-door/retention"Response:
{
"status": "updated"
}Endpoint: GET /api/stats
Get system statistics including storage usage and recording counts.
Request:
curl -u username:password \
"http://localhost:9090/api/stats"Response:
{
"total_bytes": 1073741824,
"used_bytes": 536870912,
"recording_count": 1000,
"camera_count": 4
}Endpoint: GET /api/stats/trends
Get storage usage trends over time.
Request:
curl -u username:password \
"http://localhost:9090/api/stats/trends"Response:
{
"trends": [
{
"date": "2024-01-01",
"total_bytes": 1000000000,
"used_bytes": 500000000,
"recording_count": 950
}
]
}Endpoint: GET /api/settings
Get current configuration settings.
Request:
curl -u username:password \
"http://localhost:9090/api/settings"Response:
{
"server": {
"listen": ":9090"
},
"storage": {
"root_dir": "/var/lib/mibee-nvr",
"segment_duration": "30s"
},
"cleanup": {
"retention_days": 30,
"check_interval": "1h",
"disk_threshold_percent": 95
},
"auth": {
"username": "admin"
}
}Endpoint: PUT /api/settings
Update configuration settings.
Request Body:
{
"cleanup": {
"retention_days": 60,
"disk_threshold_percent": 90,
"check_interval": "30m"
}
}Request:
curl -u username:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"cleanup": {
"retention_days": 60,
"disk_threshold_percent": 90,
"check_interval": "30m"
}
}' \
"http://localhost:9090/api/settings"Response:
{
"status": "updated"
}Endpoint: GET /api/settings/merge
Get global merge settings configuration.
Request:
curl -u username:password \
"http://localhost:9090/api/settings/merge"Response:
{
"enabled": true,
"check_interval": "1h",
"window_size": "1h",
"batch_limit": 200,
"min_segment_age": "10m",
"min_segments_to_merge": 3
}Endpoint: PUT /api/settings/merge
Update global merge settings.
Request Body:
{
"enabled": true,
"check_interval": "30m",
"window_size": "2h",
"batch_limit": 100,
"min_segment_age": "15m",
"min_segments_to_merge": 5
}Request:
curl -u username:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"check_interval": "30m",
"batch_limit": 100
}' \
"http://localhost:9090/api/settings/merge"Response:
{
"status": "updated"
}Endpoint: POST /api/onvif/discover
Discover ONVIF devices on the network.
Request Body:
{
"timeout": 5,
"target": "192.168.1.0/24"
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"timeout": 5
}' \
"http://localhost:9090/api/onvif/discover"Response:
{
"devices": [
{
"url": "http://192.168.1.104:80/onvif/device_service",
"name": "Camera 1",
"model": "ABC-123",
"location": "Office"
}
]
}Endpoint: GET /api/onvif/discover/{ip}
Get detailed information about a specific ONVIF device.
Request:
curl -u username:password \
"http://localhost:9090/api/onvif/discover/192.168.1.104"Response:
{
"device": {
"url": "http://192.168.1.104:80/onvif/device_service",
"name": "Camera 1",
"model": "ABC-123",
"location": "Office",
"manufacturer": "CameraCo",
"firmware_version": "1.2.3",
"serial_number": "CAM123456"
}
}Endpoint: POST /api/xiaomi/auth
Authenticate with Xiaomi cloud services.
Request Body:
{
"username": "xiaomi@example.com",
"password": "password123"
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"username": "xiaomi@example.com",
"password": "password123"
}' \
"http://localhost:9090/api/xiaomi/auth"Response:
{
"user_id": "1234567890",
"token": "xiaomi_token_123",
"region": "cn"
}Endpoint: POST /api/xiaomi/captcha
Get captcha for Xiaomi authentication.
Request Body:
{
"username": "xiaomi@example.com"
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"username": "xiaomi@example.com"
}' \
"http://localhost:9090/api/xiaomi/captcha"Response:
{
"captcha_id": "captcha_123",
"captcha_image": "base64_encoded_image"
}Endpoint: POST /api/xiaomi/verify
Verify captcha and complete authentication.
Request Body:
{
"captcha_id": "captcha_123",
"captcha_code": "ABC123",
"username": "xiaomi@example.com",
"password": "password123"
}Request:
curl -u username:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"captcha_id": "captcha_123",
"captcha_code": "ABC123",
"username": "xiaomi@example.com",
"password": "password123"
}' \
"http://localhost:9090/api/xiaomi/verify"Response:
{
"user_id": "1234567890",
"token": "xiaomi_token_123",
"region": "cn"
}Endpoint: GET /api/xiaomi/devices
Get list of Xiaomi devices from cloud.
Request:
curl -u username:password \
"http://localhost:9090/api/xiaomi/devices"Response:
{
"devices": [
{
"did": "camera_did_123",
"name": "Front Door Camera",
"model": "xiaomi.camera.v2",
"online": true
}
]
}Endpoint: POST /api/xiaomi/sync
Sync Xiaomi devices with local configuration.
Request:
curl -u username:password \
-X POST \
"http://localhost:9090/api/xiaomi/sync"Response:
{
"synced": 2,
"added": 1,
"removed": 0
}Endpoint: GET /api/merge/status
Get current merge manager status and statistics.
Request:
curl -u username:password \
"http://localhost:9090/api/merge/status"Response:
{
"enabled": true,
"error_count": 0,
"files_created": 9,
"last_run_time": "2026-05-11T06:37:41Z",
"segments_merged": 235
}Endpoint: GET /api/merge/pending
Get count of segments pending merge for each camera.
Request:
curl -u username:password \
"http://localhost:9090/api/merge/pending"Response:
{
"pending": {
"front-door": 99,
"backyard": 145
}
}Endpoint: GET /api/features
Get enabled/disabled feature flags.
Request:
curl -u username:password \
"http://localhost:9090/api/features"Response:
{
"features": {
"experimental_hls": false,
"auto_delete_old": true,
"webdav_upload": true
}
}Endpoint: PUT /api/features
Update feature flags.
Request Body:
{
"experimental_hls": true,
"auto_delete_old": false
}Request:
curl -u username:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"experimental_hls": true,
"auto_delete_old": false
}' \
"http://localhost:9090/api/features"Response:
{
"status": "updated"
}Endpoint: POST /api/backup
Create a backup of the database and configuration.
Request:
curl -u username:password \
-X POST \
"http://localhost:9090/api/backup"Response:
{
"backup_id": "backup_1704123456",
"path": "/var/lib/mibee-nvr/backups/backup_1704123456.tar.gz",
"size_bytes": 1048576,
"created_at": "2024-01-01T12:34:56Z"
}Endpoint: GET /api/backups
List available backups.
Request:
curl -u username:password \
"http://localhost:9090/api/backups"Response:
{
"backups": [
{
"backup_id": "backup_1704123456",
"path": "/var/lib/mibee-nvr/backups/backup_1704123456.tar.gz",
"size_bytes": 1048576,
"created_at": "2024-01-01T12:34:56Z"
}
]
}All error responses follow this format:
{
"error": "Error message",
"code": "ERROR_CODE"
}| Code | Description | HTTP Status |
|---|---|---|
CAMERA_NOT_FOUND |
Camera with specified ID does not exist | 404 |
CAMERA_ALREADY_RUNNING |
Camera recorder is already active | 400 |
CAMERA_DISABLED |
Camera is disabled and cannot be started | 400 |
CAMERA_ALREADY_EXISTS |
Camera with specified ID already exists | 409 |
RECORDING_NOT_FOUND |
Recording with specified ID does not exist | 404 |
STORAGE_FULL |
Disk space is critically low | 507 |
AUTH_REQUIRED |
Authentication is required | 401 |
AUTH_FAILED |
Authentication credentials were rejected | 401 |
INVALID_INPUT |
Request contains invalid parameters | 400 |
PATH_TRAVERSAL |
Path traversal attempt detected | 400 |
HLS_MAX_STREAMS |
Maximum concurrent HLS stream limit reached | 503 |
HLS_UNSUPPORTED_CODEC |
Camera codec is not supported for HLS streaming | 400 |
ONVIF_NOT_CAMERA |
Device is not an ONVIF camera | 400 |
ONVIF_CONNECTION_FAILED |
Failed to connect to ONVIF device | 500 |
ONVIF_NO_PROFILES |
No media profiles found for ONVIF camera | 400 |
INTERNAL |
Internal server error | 500 |
{
"error": "authentication failed: invalid username or password",
"code": "AUTH_FAILED"
}{
"error": "camera not found: non-existent-camera",
"code": "CAMERA_NOT_FOUND"
}{
"error": "invalid input: camera URL must be valid",
"code": "INVALID_INPUT"
}{
"error": "storage full: disk space critically low",
"code": "STORAGE_FULL"
}| Status Code | Description |
|---|---|
| 200 | OK - Request successful |
| 201 | Created - Resource successfully created |
| 400 | Bad Request - Invalid request parameters |
| 401 | Unauthorized - Authentication failed or required |
| 403 | Forbidden - Resource access not allowed |
| 404 | Not Found - Resource does not exist |
| 409 | Conflict - Resource conflict (e.g., duplicate camera ID) |
| 500 | Internal Server Error - Server-side error |
| 503 | Service Unavailable - Service temporarily unavailable (e.g., max streams reached) |
| 507 | Insufficient Storage - Disk space insufficient |
# Test health endpoint (no auth required)
curl http://localhost:9090/api/health
# Test authentication
curl -u admin:password http://localhost:9090/api/cameras# List all recordings
curl -u admin:password "http://localhost:9090/api/recordings"
# Add a new camera
curl -u admin:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"name": "Living Room Cam",
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.50:554/stream",
"enabled": true
}' \
"http://localhost:9090/api/cameras"
# Download a recording
curl -u admin:password \
-o recording.mp4 \
"http://localhost:9090/api/recordings/1704123456789012345/download"
# Update settings to clean up recordings older than 7 days
curl -u admin:password \
-X PUT \
-H "Content-Type: application/json" \
-d '{
"cleanup": {
"retention_days": 7
}
}' \
"http://localhost:9090/api/settings"
# Test camera connection
curl -u admin:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"protocol": "rtsp",
"encoding": "h264",
"url": "rtsp://192.168.1.100:554/stream",
"username": "admin",
"password": "secret"
}' \
"http://localhost:9090/api/cameras/test-connection"# Get HLS playlist
curl -u admin:password \
"http://localhost:9090/api/cameras/living-room/stream/stream.m3u8"
# Get HLS segment
curl -u admin:password \
"http://localhost:9090/api/cameras/living-room/stream/segment_001.ts"# Authenticate with Xiaomi cloud
curl -u admin:password \
-X POST \
-H "Content-Type: application/json" \
-d '{
"username": "xiaomi@example.com",
"password": "password123"
}' \
"http://localhost:9090/api/xiaomi/auth"
# List Xiaomi devices
curl -u admin:password \
"http://localhost:9090/api/xiaomi/devices"Endpoint: GET /api/transcoding/check
Performs a self-check of system transcoding capabilities including hardware validation, FFmpeg availability, and performance estimation.
Request:
curl -u admin:password \
"http://localhost:9090/api/transcoding/check"Response:
{
"supported": true,
"ffmpeg_status": "available",
"encoders": {
"h264": "libx264",
"h265": "libx265"
},
"warnings": [],
"max_concurrent": 2,
"estimated_fps": 3.5,
"total_cores": 4,
"total_memory_mb": 1024,
"h264_encoder_type": "software",
"h265_encoder_type": "software",
"devices": [
{
"type": "cpu",
"name": "ARMv7 Processor rev 5 (v7l)"
}
]
}Response Fields:
| Field | Type | Description |
|---|---|---|
supported |
boolean | Whether transcoding is supported |
ffmpeg_status |
string | FFmpeg status: "available", "downloading", "not_installed", "failed" |
encoders |
object | Available encoder libraries (h264, h265) |
warnings |
array[] | Human-readable warnings about limitations |
max_concurrent |
integer | Estimated maximum concurrent transcoding streams |
estimated_fps |
float | Estimated transcoding FPS on this hardware |
total_cores |
integer | Total CPU cores available |
total_memory_mb |
integer | Total system memory in MB |
h264_encoder_type |
string | "software", "hardware", or "unknown" |
h265_encoder_type |
string | "software", "hardware", or "unknown" |
devices |
array[] | Hardware device information |
GitHub | Report Issue | MIT License
Setup & Basics
Camera & Streaming
Integrations
Advanced
安装配置
摄像头与流媒体
集成
进阶