Skip to main content
🤖AI-generated documentation curatedAI Generated
This page was drafted by an AI assistant and may contain inaccuracies. This content has been reviewed by a human curator.
About content generation types
🤖
AI GeneratedPage drafted entirely by AI from codebase or prompt instructions.
(e.g., docs generated from codebase analysis)
← this page
✋→🤖
AI TransformattedHuman provided raw material; AI restructured it into a different format.
(e.g., livestream → blog post, meeting notes → docs)
Human GeneratedPage written entirely by a human author.
(e.g., hand-written tutorial)
More info about content generation types ↗

API Reference

The SkellyCam server exposes a REST API for camera management and a WebSocket endpoint for real-time streaming. Interactive Swagger documentation is available at http://localhost:53117/docs when the server is running.

info

The localhost links on this page will only work if the SkellyCam server is running — either through the desktop app or as a standalone server.

What is a REST API?

A REST API (Representational State Transfer Application Programming Interface) is a way for programs to communicate over HTTP — the same protocol your browser uses. Instead of clicking buttons in a UI, you send HTTP requests (like GET, POST, DELETE) to specific URLs, and the server responds with data (usually JSON). This is how the SkellyCam frontend communicates with the Python server, and it's also how you can build your own tools on top of SkellyCam.

Learn more: REST API (Wikipedia)

Base URL

All endpoints are served from http://localhost:53117. Camera-specific endpoints are prefixed with /skellycam.

App Endpoints

GET /health

Health check endpoint.

Response: "Hello👋" (200 OK)

GET /shutdown

Initiates graceful server shutdown. Sets the global kill flag, sends SIGTERM to the server process, and returns immediately.

Response:

{
"status": "shutdown_initiated",
"message": "Server shutting down. Goodbye!"
}

Camera Endpoints

All camera endpoints are prefixed with /skellycam/camera.

POST /skellycam/camera/detect

Detects available camera devices on the system.

Query Parameters:

ParameterTypeDefaultDescription
filter_virtualbooltrueExclude virtual cameras from results
backend_idint | nullnullOpenCV backend ID to use for detection

Response:

{
"cameras": [
{
"index": 0,
"name": "HD Webcam",
"vendor_id": 1234, // Who made this camera? May not be accurate in some cameras
"product_id": 5678, // Product id for this camera? May not be accurate in some cameras
"path": "/dev/video0", //Note - this varies by OS, hence the challenges in Issue #[Mac/Linux Issue]
"backend_id": 200, // Add a link to a cv2 page matching int's to backend. Note it should match the backend_name
"backend_name": "V4L2"
}
]
}

GET /skellycam/camera/microphone/detect

Detects available microphone devices on the system. Returns a mapping of device index to device name.

Response:

{
"microphones": {
"0": "Built-in Microphone",
"1": "USB Audio Device"
}
}

POST /skellycam/camera/group/apply

Creates a new camera group or updates an existing one. If the provided camera IDs match an existing group, the group's settings are updated; otherwise, a new group is created and started.

Request Body:

{
"camera_configs": {
"000": {
"camera_id": "000",
"camera_index": 0,
"camera_name": "Camera-000",
"use_this_camera": true,
"resolution": { "width": 1280, "height": 720 },
"framerate": -1,
"color_channels": 3,
"pixel_format": "RGB",
"exposure_mode": "MANUAL",
"exposure": -7,
"rotation": -1,
"capture_fourcc": "MJPG",
"writer_fourcc": "X264"
}
}
}

Response:

{
"group_id": "group-0", // in practice, this number is the last 6 digits of a UUID
"camera_configs": {
"0": { }
}
}

POST /skellycam/camera/group/all/record/start

Starts recording for all active camera groups.

Request Body:

{
"recording_name": "2024-09-15T14_30_00", // Default is ISO860 file-name safe datetime string with optional _tag. Must be unique within recording directory
"recording_directory": "~/skellycam_data/recordings",
"mic_device_index": -1
}

All fields have defaults. mic_device_index: -1 disables audio recording. mic_device_index: 0 uses default microphone.

Response: true (200 OK)

GET /skellycam/camera/group/all/record/stop

Stops recording for all active camera groups. Triggers timestamp processing and statistics generation.

Response: true (200 OK)

DELETE /skellycam/camera/group/close/all

Closes all camera groups, releasing all camera resources and stopping all worker processes.

Response: true (200 OK)

GET /skellycam/camera/group/all/pause_unpause

Toggles pause/unpause on all camera groups. When paused, cameras stop capturing frames but remain open.

Response: true (200 OK)

WebSocket Endpoint

WS /skellycam/websocket/connect

Persistent WebSocket connection for real-time frame streaming, log forwarding, and application state updates. See WebSocket Protocol for the full protocol specification.

Playback Endpoints

All playback endpoints are prefixed with /skellycam/playback. They serve pre-recorded video files over HTTP for browser-native <video> playback with full seeking support via HTTP range requests.

GET /skellycam/playback/recordings

Lists available recording directories in the default recordings folder (~/skellycam_data/recordings/).

Response:

[
{
"name": "2024-09-15T14_30_00",
"path": "/home/user/skellycam_data/recordings/2024-09-15T14_30_00",
"video_count": 3,
"total_size_bytes": 157286400,
"created_timestamp": "2024-09-15T14:30:00",
"total_frames": 9000,
"duration_seconds": 300.0,
"fps": 30.0
}
]

POST /skellycam/playback/load

Loads a recording folder for playback. The server validates the path, discovers video files (checking both the folder directly and a synchronized_videos/ subfolder), and makes them available for streaming.

Request Body:

{
"recording_path": "~/skellycam_data/recordings/2024-09-15T14_30_00"
}

Response:

{
"recording_path": "/home/user/skellycam_data/recordings/2024-09-15T14_30_00",
"videos": [
{
"video_id": "recording.camera.id0.idx0",
"filename": "recording.camera.id0.idx0.mp4",
"size_bytes": 52428800,
"stream_url": "/skellycam/playback/video/recording.id0.idx0"
}
]
}

GET /skellycam/playback/video/{video_id}

Streams a loaded video file. The response is a standard FileResponse with the correct Content-Type header, and Starlette handles HTTP range requests automatically — this enables browser-native seeking, buffering, and hardware-accelerated decoding via <video> elements.

GET /skellycam/playback/timestamps

Returns frame timestamps for all currently loaded videos.

Response:

{
"timestamps": {
"recording.camera0": [0.0, 33.3, 66.7],
"recording.camera1": [0.0, 33.3, 66.7]
}
}

Videos without discoverable timestamp CSVs are silently omitted from the response.

GET /skellycam/playback/timestamps/{video_id}

Returns metadata about the timestamp CSV for a given video, if available. Searches the recording's timestamps/camera_timestamps/ folder.

Error Handling

All endpoints return standard HTTP error codes:

  • 200 — Success
  • 400 — Bad request (invalid parameters)
  • 500 — Internal server error (with error detail in response body)

Errors are returned as:

{
"detail": "Error description string"
}