Summary
SecuritySpy is a macOS-based NVR/video surveillance server from Ben Software. This spec covers the built-in web server's HTTP API used to control PTZ cameras, arm/disarm capture modes, trigger motion detection, manage schedules, read system info, and subscribe to a live event stream. HTTP and RTSP share the same default port (8000 for HTTP, 8001 for HTTPS).
Transport
protocols:
- http
- tcp # RTSP shares the HTTP port per source
addressing:
port: 8000
base_url: "http://{address}/" # UNRESOLVED: base path not specified beyond resource names
auth:
type: basic # inferred: URL-embedded username:password plus auth=base64(username:password) parameter
# UNRESOLVED: detailed auth flow not fully specified; source warns URL-embedded creds insecure
Traits
- powerable # UNRESOLVED: no explicit power on/off commands in source
- routable # UNRESOLVED: inferred from PTZ direction commands
- queryable # inferred from systemInfo, cameramodes, getptzcapabilities queries
Actions
- id: ptz_command
label: PTZ Command
kind: action
command: "ptz/command?cameraNum={cameraNum}&command={command}[&speed={speed}]"
params:
- name: cameraNum
type: integer
description: Camera number as displayed in Camera Info window
- name: command
type: integer
description: "PTZ command number (1=Left, 2=Right, 3=Up, 4=Down, 5=Zoom in, 6=Zoom out, 7=Home, 8=Up-left, 9=Up-right, 10=Down-left, 11=Down-right, 12-19=Preset 1-8, 99=Stop, 112-119=Save Preset 1-8)"
- name: speed
type: integer
description: Movement speed (1-100); optional
- id: ptz_capabilities
label: Get PTZ Capabilities
kind: query
command: "getptzcapabilities?cameraNum={cameraNum}"
params:
- name: cameraNum
type: integer
description: Camera number
- id: set_schedule
label: Set Schedule / Override
kind: action
command: "setSchedule?cameraNum={cameraNum}&schedule={schedule}&override={override}&mode={mode}"
params:
- name: cameraNum
type: integer
description: Camera number, or -1 for all cameras
- name: schedule
type: integer
description: "0=Unarmed 24/7, 1=Armed 24/7, 2=Armed Sunrise-Sunset, 3=Armed Sunset-Sunrise, or custom schedule ID from systemInfo"
- name: override
type: integer
description: "0=None, 1=Unarmed until next event, 2=Armed until next event, 3=Unarmed 1h, 4=Armed 1h, 5=Unarmed 2h, 6=Armed 2h, 7=Unarmed 3h, 8=Armed 3h, 9=Unarmed 4h, 10=Armed 4h, 11=Unarmed 5h, 12=Armed 5h, 13=Unarmed 6h, 14=Armed 6h"
- name: mode
type: string
description: "Mode letters, e.g. C, M, A or any combo: C=Continuous, M=Motion, A=Actions"
- id: invoke_schedule_preset
label: Invoke Schedule Preset
kind: action
command: "setPreset?id={id}"
params:
- name: id
type: integer
description: Schedule preset ID from systemInfo
- id: get_camera_modes
label: Get Camera Modes
kind: query
command: "cameramodes?cameraNum={cameraNum}"
params:
- name: cameraNum
type: integer
description: Camera number
- id: settings_general
label: General Settings (POST)
kind: action
command: "POST settings-general"
params:
- name: autoReopen
type: integer
description: Reopen after crash (0/1)
- name: allowSleep
type: integer
description: Allow computer sleep (0/1)
- name: errWindow
type: integer
description: Display error window (0/1)
- name: dismissAlerts
type: integer
description: Dismiss alerts after 1 minute (0/1)
- name: sendDiagnostics
type: integer
description: Send diagnostics to developer (0/1)
- name: updateNotify
type: integer
description: Show update notifications (0/1)
- name: suspendMd
type: integer
description: Suspend motion detection when not needed (0/1)
- name: suspendDecoding
type: integer
description: Suspend video decoding when not needed (0/1)
- name: fullVol
type: integer
description: Set computer to full volume before playing sounds (0/1)
- name: hissReduction
type: integer
description: Hiss reduction (0/1)
- name: muteIncoming
type: integer
description: Mute incoming audio when sending audio to camera (0/1)
- name: sysName
type: string
description: CCTV system name
- name: settingsPassword
type: string
description: Password for settings access
- name: quittingPassword
type: string
description: Password for quitting
- name: dateFormat
type: integer
description: Date display format (0-7)
- name: timeFormat
type: integer
description: Time display format (0=24hr, 1=12hr)
- name: thumbCrop
type: integer
description: Motion thumbnail crop (0-100, 100=widest)
- name: audioDevice
type: string
description: Two-way audio source name
- name: audioDeviceVol
type: integer
description: Two-way audio source volume (1-250, 100=full)
- id: settings_display
label: Display Settings (POST)
kind: action
command: "POST settings-display"
params:
- name: camInfo
type: integer
description: Show camera info in video windows (0/1)
- name: floatWindows
type: integer
description: Float video windows over other apps (0/1)
- name: motionBox
type: integer
description: Red box around moving objects (0/1)
- name: kioskMode
type: integer
description: Go full screen at launch and after inactivity (0/1)
- name: lowRate
type: integer
description: Reduced live video frame rate (0/1)
- name: autoClose
type: integer
description: Auto-close video windows after inactivity (0/1)
- name: autoCloseMins
type: integer
description: Minutes of inactivity before auto-close
- name: cropMode
type: integer
description: "Live video crop mode (0=black bars, 1=crop, 2=stretch)"
- name: displayQuality
type: integer
description: "Live video display quality (0=auto, 1-4)"
- name: divThickness
type: integer
description: Divider line thickness in pixels
- name: replaySeconds
type: integer
description: Instant video replay duration in seconds
- id: settings_storage
label: Storage Settings (POST)
kind: action
command: "POST settings-storage"
params:
- name: path
type: string
description: Default capture destination
- name: removeByAge
type: integer
description: Delete files older than specified age (0/1)
- name: removeAgeSys
type: integer
description: Removal age on system volume in days
- name: removeAgeNonSys
type: integer
description: Removal age on non-system volumes in days
- name: removeBySpace
type: integer
description: Delete old files below free space threshold (0/1)
- name: removeGbSys
type: integer
description: Removal threshold on system drive in GB (0=auto)
- name: removeGbNonSys
type: integer
description: Removal threshold on non-system drives in GB (0=auto)
- name: diskWaitTime
type: integer
description: Volume mount timeout in seconds
- name: usageWarningGb
type: integer
description: Usage warning threshold in GB
- id: settings_compression
label: Compression Settings (POST)
kind: action
command: "POST settings-compression"
params:
- name: videoCodec
type: integer
description: "Video codec (4=JPEG, 5=H.264, 6=H.265)"
- name: videoQuality
type: integer
description: Video quality (1-100)
- name: audioCodec
type: integer
description: "Audio codec (0=none, 2=μ-Law, 3=AAC)"
- name: audioQuality
type: integer
description: Audio quality (1-100)
- name: jpegQuality
type: integer
description: JPEG quality (1-100)
- name: webQuality
type: integer
description: Web streaming quality (1-100)
- id: settings_email
label: Email Settings (POST)
kind: action
command: "POST settings-email"
params:
- name: imageCount
type: integer
description: Number of images per email
- name: imageFps
type: integer
description: Image capture rate
- name: imageSize
type: integer
description: "Image size (0=full, 1=half, 2=quarter)"
- name: subject
type: string
description: Subject text
- name: reportsEmail
type: string
description: Errors/warnings destination
- name: statsEmail
type: string
description: Daily statistics destination
- name: downtimeEmail
type: string
description: Downtime warnings destination
- name: sendingMethod
type: integer
description: "Sending method (0=relay, 1=SMTP)"
- name: address
type: string
description: SMTP server address
- name: fromName
type: string
description: SMTP From name
- name: fromEmail
type: string
description: SMTP From email
- name: username
type: string
description: SMTP username
- name: password
type: string
description: SMTP password
- name: encryption
type: integer
description: "SMTP encryption (0=none, 2=SSL)"
- id: settings_web
label: Web Settings (POST)
kind: action
command: "POST settings-web"
params:
- name: http
type: integer
description: Enable HTTP server (0/1)
- name: https
type: integer
description: Enable HTTPS server (0/1)
- name: portHttp
type: integer
description: HTTP port
- name: portHttps
type: integer
description: HTTPS port
- name: autoNatHttp
type: integer
description: Automatic port forwarding for HTTP (0/1)
- name: autoNatHttps
type: integer
description: Automatic port forwarding for HTTPS (0/1)
- name: ddnsName
type: string
description: Dynamic DNS name
- name: insecure
type: integer
description: Reduce HTTPS security for older clients (0/1)
- name: bonjour
type: integer
description: Advertise via Bonjour (0/1)
- name: log
type: integer
description: Write log of all connections (0/1)
- id: settings_cameras
label: Camera Settings (POST)
kind: action
command: "POST settings-cameras"
params:
- name: cameraNum
type: integer
description: REQUIRED. Camera number
- name: address
type: string
description: IP or hostname
- name: portHttp
type: integer
description: HTTP port
- name: portRtsp
type: integer
description: RTSP port
- name: username
type: string
description: Camera username
- name: password
type: string
description: Camera password
- name: format
type: integer
description: Video streaming format (0-15)
- name: inputNum
type: integer
description: Input/stream number
- name: request
type: string
description: Manual profile path
- name: recompressVideo
type: integer
description: Recompress video (0/1)
- name: recompressAudio
type: integer
description: Recompress audio (0/1)
- name: enabled
type: integer
description: Enable camera (0/1)
- name: name
type: string
description: Camera name
- name: transformation
type: integer
description: Transformation (0-5)
- name: brightness
type: integer
description: Brightness (0-100)
- name: contrast
type: integer
description: Contrast (0-100)
- name: overlay
type: integer
description: Text overlay enabled (0/1)
- name: overlayText
type: string
description: Text overlay text
- name: overlaySize
type: integer
description: Text overlay font size
- name: overlayPos
type: integer
description: Text overlay position (0-3)
- name: audioDevice
type: string
description: "Device name (n=this network device, x=none)"
- name: path
type: string
description: Camera-specific capture destination
- name: motionSensitivity
type: integer
description: Motion detection sensitivity (1-100)
- name: mcTriggerMotion
type: integer
description: Motion-capture motion trigger (0/1)
- name: mcTriggerMotionA
type: integer
description: Motion-capture animal motion trigger (0/1)
- name: mcTriggerMotionH
type: integer
description: Motion-capture human motion trigger (0/1)
- name: mcTriggerMotionV
type: integer
description: Motion-capture vehicle motion trigger (0/1)
- name: mcTriggerArrivesA
type: integer
description: Motion-capture animal arrival trigger (0/1)
- name: mcTriggerArrivesH
type: integer
description: Motion-capture human arrival trigger (0/1)
- name: mcTriggerArrivesV
type: integer
description: Motion-capture vehicle arrival trigger (0/1)
- name: mcTriggerDepartsA
type: integer
description: Motion-capture animal departure trigger (0/1)
- name: mcTriggerDepartsH
type: integer
description: Motion-capture human departure trigger (0/1)
- name: mcTriggerDepartsV
type: integer
description: Motion-capture vehicle departure trigger (0/1)
- name: mcTriggerAudio
type: integer
description: Motion-capture audio trigger (0/1)
- name: aTriggerMotion
type: integer
description: Actions motion trigger (0/1)
- name: aTriggerMotionA
type: integer
description: Actions animal motion trigger (0/1)
- name: aTriggerMotionH
type: integer
description: Actions human motion trigger (0/1)
- name: aTriggerMotionV
type: integer
description: Actions vehicle motion trigger (0/1)
- name: aTriggerArrivesA
type: integer
description: Actions animal arrival trigger (0/1)
- name: aTriggerArrivesH
type: integer
description: Actions human arrival trigger (0/1)
- name: aTriggerArrivesV
type: integer
description: Actions vehicle arrival trigger (0/1)
- name: aTriggerDepartsA
type: integer
description: Actions animal departure trigger (0/1)
- name: aTriggerDepartsH
type: integer
description: Actions human departure trigger (0/1)
- name: aTriggerDepartsV
type: integer
description: Actions vehicle departure trigger (0/1)
- name: aTriggerAudio
type: integer
description: Actions audio trigger (0/1)
- name: ccMovie
type: integer
description: Continuous-capture movie (0/1)
- name: ccMovieFps
type: integer
description: Continuous-capture movie fps
- name: ccMoviePlaybackFps
type: integer
description: Continuous-capture movie playback fps
- name: ccFreq
type: integer
description: "Continuous-capture new file frequency (0-2)"
- name: ccImage
type: integer
description: Continuous-capture images (0/1)
- name: ccImageInterval
type: integer
description: Continuous-capture images interval seconds
- name: webcamName
type: string
description: Webcam image filename
- name: webcamFreq
type: integer
description: Webcam image frequency seconds
- name: ccRemoveAge
type: integer
description: Continuous-capture auto-delete days
- name: mcMovie
type: integer
description: Motion-capture movie (0/1)
- name: mcMovieFps
type: integer
description: Motion-capture movie fps
- name: mcMoviePre
type: integer
description: Motion-capture pre-capture seconds
- name: mcMoviePost
type: integer
description: Motion-capture post-capture seconds
- name: mcImage
type: integer
description: Motion-capture images (0/1)
- name: mcImageInterval
type: integer
description: Motion-capture images interval seconds
- name: mcImagePost
type: integer
description: Motion-capture post-capture seconds
- name: mcRemoveAge
type: integer
description: Motion-capture auto-delete days
- name: aSoundName
type: string
description: Sound filename
- name: aSoundDuration
type: integer
description: Sound duration seconds
- name: aSoundVolume
type: integer
description: Sound volume (1-100)
- name: aScriptName
type: string
description: Script name
- name: aEmail
type: string
description: Email address(es)
- name: aShellCommand
type: string
description: Shell command
- name: aComeFront
type: integer
description: Come to front (0/1)
- name: aRedBox
type: integer
description: Red box highlight (0/1)
- name: aNotification
type: integer
description: macOS notification (0/1)
- name: aDelay
type: integer
description: Delay before seconds
- name: aReset
type: integer
description: Reset time seconds
- id: trigger_motion_detection
label: Trigger Motion Detection
kind: action
command: "triggermd?cameraNum={cameraNum}"
params:
- name: cameraNum
type: integer
description: Camera number, or -1 for all
- id: get_system_info
label: Get System Information
kind: query
command: "systemInfo?format={format}"
params:
- name: format
type: string
description: "Optional: xml or json. Omit for legacy XML."
- id: subscribe_event_stream
label: Subscribe Event Stream
kind: action
command: "eventStream?version=3[&format=multipart]"
params:
- name: format
type: string
description: "Optional: multipart. Otherwise plain text."
Feedbacks
- id: ptz_command_ack
type: enum
values: ["OK"]
description: Returned by ptz/command on success
- id: set_schedule_ack
type: enum
values: ["OK"]
description: Returned by setSchedule on success
- id: set_preset_ack
type: enum
values: ["OK"]
description: Returned by setPreset on success
- id: camera_modes
type: object
description: "Three lines of plain text, one per mode: C:ARMED/DISARMED, M:ARMED/DISARMED, A:ARMED/DISARMED. Lines may be separated by LF (10) or CR (13)."
- id: ptz_capabilities_bitmask
type: integer
description: "Single number from getptzcapabilities. Convert to binary; bits 1=Pan/Tilt, 2=Home, 4=Zoom, 8=Presets, 16=Speed, 32=Continuous movement."
- id: trigger_reason_code
type: integer
description: "Bitfield from TRIGGER_M/TRIGGER_A: bit0=motion, bit1=audio, bit2=AppleScript, bit3=camera event, bit4=web server event, bit5=other-camera trigger, bit6=manual, bit7=human movement, bit8=vehicle movement, bit9=HomeKit, bit10=animal movement, bit11=human arrival, bit12=human departure, bit13=vehicle arrival, bit14=vehicle departure, bit15=animal arrival, bit16=animal departure"
Variables
# UNRESOLVED: source documents per-camera static config (settings-cameras) but no
# run-time variable read/write endpoint distinct from settings-cameras POST.
Events
- id: arm_c
type: notification
description: Camera's Continuous Capture mode armed
- id: disarm_c
type: notification
description: Camera's Continuous Capture mode disarmed
- id: arm_m
type: notification
description: Camera's Motion Capture mode armed
- id: disarm_m
type: notification
description: Camera's Motion Capture mode disarmed
- id: arm_a
type: notification
description: Camera's Actions mode armed
- id: disarm_a
type: notification
description: Camera's Actions mode disarmed
- id: error
type: notification
description: Error for specified camera; INFO=error codes
- id: configchange
type: notification
description: Configuration change for specified camera
- id: offline
type: notification
description: Specified camera went offline
- id: online
type: notification
description: Specified camera came online
- id: motion
type: notification
description: "Motion detected; INFO=X Y W H bounding box"
- id: motion_end
type: notification
description: Motion stopped (issued after MOTION)
- id: classify
type: notification
description: "AI classification; INFO=prediction percentages (HUMAN/VEHICLE/ANIMAL)"
- id: trigger_m
type: notification
description: "Motion Capture triggered; INFO=trigger reason code"
- id: trigger_a
type: notification
description: "Actions triggered; INFO=trigger reason code"
- id: file
type: notification
description: "Recording/file complete; INFO=full path to file"
- id: null
type: notification
description: Heartbeat sent every 10 seconds
Macros
# UNRESOLVED: source describes no multi-step macro sequences
Safety
confirmation_required_for: []
interlocks: []
# UNRESOLVED: source contains no explicit safety warnings, interlocks, or
# power-on sequencing requirements
Notes
- HTTP and RTSP share the same default port: 8000 for HTTP/RTSP, 8001 for HTTPS/RTSPS.
- Settings POSTs accept only the parameters the caller wishes to change; unspecified keys are left untouched.
- Authentication can be passed via URL-embedded
username:password@or via theauth=base64(user:pass)query parameter. Source warns URL-embedded credentials are insecure and recommends the SecuritySpy URL Generator for secure tokens. setSchedulereturns plain "OK" on success; no per-field error format documented.- Continuous-movement PTZ cameras (bit 6 of ptz_capabilities) require command 99 (Stop) after every move/zoom command 1-11.
- Event stream uses a 14-character timestamp
YYYYMMDDHHMMSS. New event types may be added; clients should ignore unknown types.
Provenance
source_domains:
- bensoftware.com
source_urls:
- https://bensoftware.com/securityspy/web-server-spec.html
- https://bensoftware.com/securityspy/helpapplescript.html
- https://bensoftware.com/securityspy/manual/
- https://bensoftware.com/securityspy/help.php
retrieved_at: 2026-06-12T05:25:54.181Z
last_checked_at: 2026-06-12T19:12:21.249Z
Verification Summary
verdict: verified
checked_at: 2026-06-12T19:12:21.249Z
matched_actions: 15
action_count: 15
confidence: medium
summary: "All 15 spec actions matched source endpoints with exact parameter signatures; transport parameters verified. (9 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "list any major gaps here"
- "base path not specified beyond resource names"
- "detailed auth flow not fully specified; source warns URL-embedded creds insecure"
- "no explicit power on/off commands in source"
- "inferred from PTZ direction commands"
- "source documents per-camera static config (settings-cameras) but no"
- "source describes no multi-step macro sequences"
- "source contains no explicit safety warnings, interlocks, or"
- "settingsGeneral/settings-display/etc. POST request/response body schema beyond key=value form not documented. Trigger reason code binary layout in source is 1-indexed (1=Video motion, 2=Audio) not 0-indexed; map above uses 0-indexed bits per the source's bit-0=LSB rule."
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0