IP Camera API Reference PRO

Complete HTTP and WebSocket API documentation for integrating with IP Camera.

Pro Feature: Direct API access (curl, scripts, Home Assistant) requires a Pro license. The web dashboard is available to all users.

Overview

The IP Camera API provides HTTP endpoints and WebSocket communication for controlling camera settings, accessing video streams, and integrating with external systems like Home Assistant.

Base URL

All API requests are made to the device's IP address on port 8443 (HTTPS):

Base URL
https://<device-ip>:8443

Pro vs Free Access

Access Method Free Users Pro Users
Web Dashboard (browser) Basic features only All features
Direct API (curl, scripts, Home Assistant) Blocked (403) Full access

Quick Start

Test connection
curl -k https://192.168.1.100:8443/status

Note: The -k flag accepts the self-signed certificate. For production, install the certificate from /cert.

Authentication

When password protection is enabled, most endpoints require authentication.

Token-Based Auth

After authenticating via POST /auth, include the token in requests:

Authorization Header
Authorization: Bearer <token>

POST/auth

Authenticate and receive a session token.

Request
curl -k -X POST https://192.168.1.100:8443/auth \
  -H "Content-Type: application/json" \
  -d '{"password": "your_password"}'
Response
{
  "success": true,
  "token": "a1b2c3d4e5f6...",
  "csrfToken": "g7h8i9j0k1l2..."
}
Response (401 Unauthorized)
{
  "success": false,
  "error": "Invalid password"
}
Response (429 Too Many Requests)
{
  "success": false,
  "error": "Too many attempts",
  "lockout": true,
  "lockoutRemaining": 30
}

GET/auth/status

Check if authentication is enabled.

Response
{
  "enabled": true,
  "configured": true
}

POST/auth/logout

Revoke the current session token.

Response
{
  "success": true
}

Public Endpoints (No Auth Required)

Certificate Endpoints

GET/cert

Download the self-signed certificate (PEM format) for installing on client devices.

GET/cert/info

Get certificate metadata.

Response
{
  "subject": "CN=IP Camera, O=Local Network, C=US",
  "issuer": "CN=IP Camera, O=Local Network, C=US",
  "notBefore": 1707000000000,
  "notAfter": 1738536000000,
  "serialNumber": "a1b2c3d4e5f6",
  "status": "valid",
  "downloadUrl": "/cert"
}

Note: notBefore and notAfter are Unix timestamps in milliseconds.

POST/cert/regenerate

Regenerate the HTTPS certificate. Useful after IP address change. Requires authentication.

curl
curl -k -X POST -H "Authorization: Bearer YOUR_TOKEN" \
  https://192.168.1.100:8443/cert/regenerate
Response
{
  "success": true
}

CSRF Protection

State-changing requests (POST, PUT, DELETE) require CSRF protection when using cookie-based authentication.

When CSRF is Required

CSRF validation applies to requests that:

Note: Pro users using Bearer token authentication (via Authorization header) are NOT subject to CSRF checks. CSRF protection only applies to cookie-based authentication.

How to Get the CSRF Token

When authenticating via POST /auth, the response includes a csrfToken field:

POST /auth Response
{
  "success": true,
  "token": "a1b2c3d4e5f6...",
  "csrfToken": "g7h8i9j0k1l2..."
}

How to Include the CSRF Token

Include the CSRF token in the X-CSRF-Token header for all state-changing requests:

X-CSRF-Token Header
X-CSRF-Token: g7h8i9j0k1l2...

Example: Update Settings with CSRF Token

curl
curl -X POST https://192.168.1.100:8443/settings \
  -H "Cookie: session=..." \
  -H "X-CSRF-Token: your_csrf_token" \
  -H "Content-Type: application/json" \
  -d '{"frameRate": 30}'

Error Response

If the CSRF token is missing or invalid, the server returns a 403 Forbidden response:

Response (403 Forbidden)
{
  "error": "Invalid CSRF token"
}

HTTPS Requirement

All API endpoints require HTTPS (port 8443). The dashboard requires HTTPS for secure session cookies.

HTTP Redirect Server (Port 8080)

An HTTP listener on port 8080 provides friendly handling for users who type http://:

Route Type HTTP Behavior
Dashboard/UI (/, *.html, *.js, *.css) 302 Redirect to https://host:8443/...
Session endpoints (/auth, /auth/logout) 403 Forbidden with JSON error
API endpoints 403 Forbidden with JSON error
WebSocket upgrade 403 Forbidden (cannot redirect WebSocket)

Error Response Format

When HTTPS is required but the request was made over HTTP, the server returns:

Response (403 Forbidden)
{
  "error": "HTTPS required",
  "httpsPort": 8443
}

Note: Always use https:// with port 8443 for API requests. The HTTP server on port 8080 exists only to redirect users who accidentally use http://.

Reverse Proxy Support

For deployments behind a TLS-terminating proxy (nginx, Apache, Caddy, Cloudflare), the app supports the X-Forwarded-Proto header.

How It Works

  1. The proxy terminates TLS and forwards HTTP to the app
  2. Set X-Forwarded-Proto: https header in proxy config
  3. Enable reverse proxy mode in app Settings (Pro feature)
  4. The app trusts this header when reverse proxy mode is enabled

nginx Configuration Example

nginx.conf
location /ipcamera/ {
    proxy_pass https://192.168.1.100:8443/;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_ssl_verify off;
}

Security Warning: Only enable reverse proxy mode if you trust the X-Forwarded-Proto header. When enabled, the header is trusted from any source. Ensure your network prevents unauthorized clients from connecting directly to the app, bypassing the proxy.

Note: Reverse proxy mode is a PRO feature and must be enabled in app settings before the X-Forwarded-Proto header will be recognized.

Streaming

GET/stream

MJPEG video stream for viewing in browsers and media players.

HTML embed
<img src="https://192.168.1.100:8443/stream?token=YOUR_TOKEN" />

GET/snapshot

Latest JPEG frame from the video stream.

curl
curl -k "https://192.168.1.100:8443/snapshot?token=YOUR_TOKEN" -o snapshot.jpg

GET/capture

High-resolution still capture (full sensor resolution). Must be triggered via WebSocket first.

Settings

GET/settings

Get all current settings.

curl
curl -k -H "Authorization: Bearer YOUR_TOKEN" https://192.168.1.100:8443/settings
Response
{
  "resolution": "1280x720",
  "frameRate": 30,
  "jpegQuality": 85,
  "cameraId": "0",
  "torchEnabled": false,
  "audioEnabled": true,
  "rotation": 0,
  "keepScreenOn": true,
  "showPreview": true,
  "motionEnabled": true,
  "motionSensitivity": 5,
  "soundEnabled": false,
  "rtspEnabled": false,
  "mqttEnabled": false,
  "license": {
    "isPro": true,
    "state": "ACTIVE"
  }
}

POST/settings

Update settings. Partial updates allowed.

curl
curl -k -X POST https://192.168.1.100:8443/settings \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"resolution": "1920x1080", "frameRate": 20}'

Available Settings

Key Type Description
Camera Settings
resolutionstringVideo resolution (e.g., "1280x720")
frameRateintFrames per second (1-60)
jpegQualityintJPEG quality for MJPEG (1-100)
cameraIdstringCamera ID ("0" = back, "1" = front)
useFrontCamerabooleanUse front camera
torchEnabledbooleanFlashlight on/off
rotationintManual rotation (0, 90, 180, 270)
Display Settings
keepScreenOnbooleanKeep screen on while streaming
showPreviewbooleanShow camera preview on device
Background Operation
runInBackgroundbooleanAllow background operation
cameraStandbyModebooleanEnter standby when no clients
Audio Settings
audioEnabledbooleanEnable audio capture
Motion Detection
motionEnabledbooleanEnable motion detection
motionSensitivityintMotion sensitivity (1-10)
motionCooldownintCooldown between events (seconds)
Sound Detection
soundEnabledbooleanEnable sound detection
soundThresholdintSound threshold (0-100)
soundCooldownintCooldown between events (seconds)
ML Classification
dogBarkClassificationEnabledbooleanEnable dog bark detection
dogBarkClassificationConfidenceintConfidence threshold (1-100)
babyCryClassificationEnabledbooleanEnable baby cry detection
babyCryClassificationConfidenceintConfidence threshold (1-100)
objectPersonDetectionEnabledbooleanEnable person detection
objectPersonDetectionConfidenceintConfidence threshold (1-100)
objectDogDetectionEnabledbooleanEnable dog object detection
objectDogDetectionConfidenceintConfidence threshold (1-100)
objectDetectionSamplingRateintSampling rate for object detection
Event History
eventHistoryEnabledbooleanEnable event history
RTSP Settings
rtspEnabledbooleanEnable RTSP server
rtspPortintRTSP port number
rtspPathstringStream path (e.g., "/stream")
rtspUsernamestringRTSP authentication username
rtspHasPasswordbooleanWhether password is set (read-only)
MQTT Settings
mqttEnabledbooleanEnable MQTT client
mqttBrokerUrlstringBroker URL
mqttPortintBroker port
mqttHasUsernamebooleanWhether username is set (read-only)
mqttHasPasswordbooleanWhether password is set (read-only)
mqttClientIdstringClient ID
mqttTopicPrefixstringTopic prefix
mqttUseTlsbooleanUse TLS encryption
mqttAcceptSelfSignedbooleanAccept self-signed certificates
mqttTelemetryIntervalSecintTelemetry interval (seconds)
mqttCommandsEnabledbooleanEnable MQTT commands

License Object (Read-Only)

The license field is a nested object that provides Pro license status information:

License Object Structure
{
  "license": {
    "isPro": true,
    "state": "ACTIVE",
    "source": "REAL_PURCHASE",
    "billing": {
      "available": true,
      "status": "CONNECTED"
    }
  }
}
Field Type Description
license.isProbooleanWhether Pro license is active
license.statestring"ACTIVE", "INACTIVE", or "UNKNOWN"
license.sourcestring"REAL_PURCHASE", "DEBUG_OVERRIDE", or "NONE"
license.billing.availablebooleanWhether billing service is available
license.billing.statusstring"CONNECTED", "UNAVAILABLE_RECOVERABLE", or "UNAVAILABLE_HARD"

Note: Fields marked (read-only) are returned by GET /settings but cannot be modified via POST /settings. Use dedicated endpoints (e.g., /api/rtsp/apply-settings, /api/mqtt/apply-settings) to update credentials.

Status & Capabilities

GET/status

Current server and streaming status.

Response
{
  "clients": 2,
  "wsClients": 1,
  "streaming": true,
  "cameraRunning": true,
  "settings": { ... }
}

GET/capabilities

Camera hardware capabilities.

Response
{
  "cameraIds": ["0", "1"],
  "resolutions": ["1280x720", "1920x1080"],
  "frameRates": [15, 20, 30, 60],
  "maxFrameRate": 60
}

POST/torch

Toggle the device flashlight/torch.

curl
curl -k -X POST -H "Authorization: Bearer YOUR_TOKEN" \
  "https://192.168.1.100:8443/torch"
Response
{
  "torchEnabled": true
}

RTSP Streaming

H.264 video streaming compatible with VLC, ffmpeg, and security camera software.

Connection Limits:

  • Maximum 10 concurrent connections globally
  • Maximum 3 concurrent connections per IP address
  • New connections are rejected when at capacity (no queueing)
  • Rejected connections receive a 503 status in RTSP

GET/api/rtsp/status

RTSP server status.

Response
{
  "enabled": true,
  "running": true,
  "port": 8554,
  "path": "/stream",
  "clients": 2
}

POST/api/rtsp/start

Start RTSP server.

POST/api/rtsp/stop

Stop RTSP server.

POST/api/rtsp/restart

Restart RTSP server with current settings.

POST/api/rtsp/settings

Update RTSP configuration.

Request
{
  "rtspPort": 8554,
  "rtspPath": "/stream",
  "rtspUsername": "admin",
  "rtspPassword": "secret"
}

POST/api/rtsp/apply-settings

Apply new RTSP settings atomically and restart the server.

Request
{
  "rtspPort": 8554,
  "rtspPath": "/stream",
  "rtspUsername": "admin",
  "rtspPassword": "secret"
}
Response
{
  "success": true
}

Connecting

ffmpeg
ffmpeg -rtsp_transport tcp -i rtsp://192.168.1.100:8554/stream -f null -
VLC
vlc rtsp://192.168.1.100:8554/stream

MQTT Integration

Integrate with Home Assistant, Node-RED, and other MQTT-based automation systems.

GET/api/mqtt/status

MQTT client connection status.

Response
{
  "enabled": true,
  "connected": true,
  "brokerUrl": "192.168.1.100",
  "port": 1883,
  "topicPrefix": "ipcamera"
}

GET/api/mqtt/settings

Get current MQTT settings (passwords redacted).

POST/api/mqtt/settings

Update MQTT configuration.

Request
{
  "mqttEnabled": true,
  "mqttBrokerUrl": "192.168.1.100",
  "mqttPort": 1883,
  "mqttTopicPrefix": "ipcamera"
}

POST/api/mqtt/test

Test MQTT broker connection.

POST/api/mqtt/apply-settings

Apply MQTT settings with password verification. Requires the current password when modifying credentials.

Request
{
  "currentPassword": "existing_password",
  "settings": {
    "mqttEnabled": true,
    "mqttBrokerUrl": "192.168.1.100",
    "mqttPort": 1883,
    "mqttUsername": "newuser",
    "mqttPassword": "newpass",
    "mqttClientId": "ipcamera-001",
    "mqttTopicPrefix": "ipcamera",
    "mqttUseTls": false,
    "mqttAcceptSelfSigned": false,
    "mqttTelemetryIntervalSec": 60,
    "mqttCommandsEnabled": false
  }
}

Note: currentPassword is only required when changing credentials (username, password) or disabling authentication. For non-credential settings, it can be omitted. First-time credential setup does not require verification.

Response (200 OK)
{
  "success": true
}
Response (403 Forbidden)
{
  "error": "Current password required for credential changes"
}

Event History

GET/events

Query detection events.

Parameter Type Description
limitintMax events (1-10000, default: 1000)
sincelongTimestamp in ms (0 = start of today)
typestringMOTION, ANY_SOUND, DOG_BARK, etc.
bucketMslongAggregate events into time buckets (60000-3600000 ms)
curl
curl -k -H "Authorization: Bearer YOUR_TOKEN" \
  "https://192.168.1.100:8443/events?since=0&type=MOTION"
Response
{
  "serverNow": 1234567890000,
  "dayStart": 1234483200000,
  "events": [
    {
      "id": 1,
      "eventId": 1001,
      "timestamp": 1234567890000,
      "type": "MOTION",
      "changedPercent": 12.5,
      "width": 1280,
      "height": 720
    },
    {
      "id": 2,
      "eventId": 1002,
      "timestamp": 1234567891000,
      "type": "ANY_SOUND",
      "db": -25.5,
      "rms": 0.45
    },
    {
      "id": 3,
      "eventId": 1003,
      "timestamp": 1234567892000,
      "type": "DOG_BARK",
      "className": "Dog",
      "confidence": 92
    },
    {
      "id": 4,
      "eventId": 1004,
      "timestamp": 1234567893000,
      "type": "OBJECT_PERSON",
      "objectClass": "person",
      "confidence": 85,
      "eventType": "appeared"
    }
  ],
  "summary": [
    { "type": "MOTION", "count": 5, "lastTimestamp": 1234567890000 },
    { "type": "ANY_SOUND", "count": 3, "lastTimestamp": 1234567891000 },
    { "type": "DOG_BARK", "count": 2, "lastTimestamp": 1234567892000 },
    { "type": "OBJECT_PERSON", "count": 1, "lastTimestamp": 1234567893000 }
  ]
}

Bucketed Queries

When bucketMs is provided, the response format changes from individual events to aggregated buckets:

Bucketed Response
{
  "buckets": [
    {
      "timestamp": 1699200000000,
      "counts": {
        "MOTION": 5,
        "ANY_SOUND": 3,
        "DOG_BARK": 1
      }
    },
    {
      "timestamp": 1699200060000,
      "counts": {
        "MOTION": 2
      }
    }
  ],
  "bucketMs": 60000,
  "timeRange": {
    "start": 1699200000000,
    "end": 1699203600000
  }
}

Tip: Use bucketed queries for time-series analytics and event frequency charts.

GET/events/range

Get time range of stored events.

curl
curl -k -H "Authorization: Bearer YOUR_TOKEN" \
  "https://192.168.1.100:8443/events/range"
Response
{
  "minTimestamp": 1234567000000,
  "maxTimestamp": 1234567890000,
  "totalEvents": 1523
}

POST/events/clear

Delete all stored events.

Parameter Type Description
confirmstringMust be true (required for safety)
curl
curl -k -X POST -H "Authorization: Bearer YOUR_TOKEN" \
  "https://192.168.1.100:8443/events/clear?confirm=true"
Response
{
  "success": true,
  "cleared": 1523
}

GET/api/storage/stats

Get storage usage statistics for event history.

curl
curl -k -H "Authorization: Bearer YOUR_TOKEN" \
  "https://192.168.1.100:8443/api/storage/stats"
Response
{
  "databaseSize": "2.5 MB",
  "databaseSizeBytes": 2621440,
  "totalEvents": 1990,
  "motionEvents": 1200,
  "soundEvents": 328,
  "eventsByType": {
    "MOTION": 1200,
    "ANY_SOUND": 300,
    "DOG_BARK": 23,
    "BABY_CRY": 5,
    "OBJECT_PERSON": 450,
    "OBJECT_DOG": 12
  },
  "minTimestamp": 1234567000000,
  "maxTimestamp": 1234567890000,
  "deviceStorageTotal": "64.0 GB",
  "deviceStorageAvailable": "32.5 GB",
  "deviceStorageTotalBytes": 68719476736,
  "deviceStorageAvailableBytes": 34896609280
}

GET/api/events/export

Export all events as CSV. PRO

curl
curl -k -H "Authorization: Bearer YOUR_TOKEN" \
  "https://192.168.1.100:8443/api/events/export" \
  -o ip-camera-events.csv

Response: CSV file with columns: id, type, timestamp, confidence, details, cameraId, resolution, frameRate, lightLevel, motionZones, thumbnailPath, metadata

Status Body Cause
403{"error":"Pro license required","feature":"event_export"}Pro license not active
500Event history unavailableDatabase not initialized

WebSocket Protocol

Real-time communication for live updates and control.

Connection

WebSocket URL
wss://192.168.1.100:8443/ws?token=YOUR_TOKEN

Connection Lifecycle

Upon successful WebSocket connection, the server sends a connected message:

Connected Message
{"type": "connected", "authenticated": true, "timestamp": 1234567890000}

Immediately after authentication, the server automatically sends a full state snapshot so the client has everything it needs without additional requests:

  1. status — streaming state, detection state, and current settings
  2. system_info — CPU, memory, battery, and stream statistics
  3. mqtt_status — MQTT connection state (enabled, connected, broker info)
  4. rtsp_status — RTSP server state (enabled, running, client count)

If authentication is required but no valid token was provided, the server sends:

Auth Required Message
{"type": "auth_required", "timestamp": 1234567890000}

The client must respond with an auth message within 10 seconds.

Client Messages

Type Description
authWebSocket authentication with token
pingKeepalive (server responds with pong)
settingUpdate a single setting
settings_batchUpdate multiple settings
captureTrigger high-res capture
enableH264Enable H.264 stream
requestKeyframeRequest H.264 keyframe
h264_qualityAdjust H.264 encoding quality (0-100)
stream_controlStart/stop streaming
audio_subscribeSubscribe to audio stream (Two-Way Audio)
audioSend audio data to device (Two-Way Audio)
ttsText-to-speech on device (Two-Way Audio)

Server Messages

Type Description
connectedInitial connection confirmation
auth_requiredAuthentication needed prompt
authAuthentication success/failure response
errorError message with code and details
pongResponse to ping keepalive
settingsSettings changed (broadcast)
setting_ackSingle setting update acknowledgment
settings_batch_ackBatch settings update acknowledgment
statusStreaming status update
system_infoDevice info (CPU, memory, battery)
h264_ackH.264 enable acknowledgment
motion_detectedMotion event
sound_detectedSound event
sound_classifiedDog bark classified
baby_cry_classifiedBaby cry classified
object_detectedPerson/dog detected
detection_frameAll tracked objects in frame
capture_readyHigh-res capture available
capture_busyCapture already in progress
mqtt_statusMQTT connection state
rtsp_statusRTSP server state
license:changedPro license status change
capabilitiesChangedCamera capabilities changed
audio_ackAudio subscribe acknowledgment
audioAudio data from device (Two-Way Audio)

Example: Auth Message

JSON
{"type": "auth", "token": "your_auth_token"}

Example: Update Setting

JSON
{"type": "setting", "key": "resolution", "value": "1920x1080"}

Example: Error Response

JSON
{"type": "error", "message": "Authentication required"}

Error Handling

HTTP Status Codes

Status Meaning
400Invalid request (bad JSON, missing fields)
401Authentication required or invalid token
403Forbidden (Pro required, HTTPS required)
429Rate limit exceeded
500Server error
503Service unavailable (camera not started)

Error Response Format

JSON
{"error": "Description of the error"}

Pro Feature Error (403)

JSON
{
  "error": "Pro license required",
  "feature": "rtsp_streaming",
  "hint": "Access this feature through the web dashboard or upgrade to Pro"
}

The feature field identifies which Pro feature was requested:

Feature ID Endpoints/Features
rtsp_streaming/api/rtsp/* endpoints
mqtt_integration/api/mqtt/* endpoints
event_history/events, /events/range, /events/clear
event_export/api/events/export
storage_analytics/api/storage/stats
certificate_download/cert

Settings Validation Error (400)

JSON
{
  "success": false,
  "errors": [
    "unknownKey: Unknown setting",
    "frameRate: Value must be between 1 and 60"
  ]
}

The errors array lists all validation failures. Each entry follows the format key: message.

Auth Lockout Error (429)

JSON
{
  "success": false,
  "error": "Too many attempts",
  "lockout": true,
  "lockoutRemaining": 30
}

After 5 failed login attempts, the account is locked for 30 seconds. The lockoutRemaining field shows seconds until retry is allowed.

Certificate

Download the self-signed certificate to eliminate browser warnings:

curl
curl -k https://192.168.1.100:8443/cert -o ipcamera.pem