Status
ONLINE
Streaming live
Recording
ACTIVE
1hr segments
Protocol
HLS
H264 stream
Camera
Loading
Loading camera...
Connecting...
CONNECTING
--:--:--PDT
PTZ Control
Zoom
🔍+
🔍−
Camera Presets — Click to Move Camera
Loading presets...
📺
Always Live to YouTube · 24/7
Pick a camera below, choose ⚡ OAuth (zero gap) or 🔑 Stream Key (simple), flip the 24/7 switch — done. Broadcasts auto-recover and survive reboots.
Loading cameras…
⚙ Admin: YouTube OAuth client credentials (one-time)
Paste OAuth credentials from your Google Cloud → Credentials page (Web application client). One-time setup — required for OAuth-mode 24/7 streaming.
Add this redirect URI to your OAuth client: https://hdrelay.io/api/admin/youtube/oauth-callback
📋 Camera Grid
Snapshots refresh every 10 seconds · click any card to watch live
Camera
Date Range
From
To
Live Timelapse —
Plays today's archive at fast speed · no build step
PDT
🕐 --:--
TIMELAPSE
Timelapse Capture
Interval
5
min · 288/day
10
min · 144/day
15
min · 96/day
Not running
Build Timelapse Video
5 fps
Slow
10 fps
Normal
24 fps
Fast
30 fps
Fastest
Select interval to see estimate
🎬 Source
📅 Time range (optional — leave blank for all snapshots)
 
Snapshots
Start timelapse to capture snapshots
Dashboard
⏳ Loading…
Cameras
total
Online
streaming live
Recordings
total clips
Rec Hours
stored
Storage
GB used
Timelapse
snapshots
Live Pushes
active streams
Bandwidth
total ingest
Data Usage
estimated
Disk Used
of total
Camera Status
Loading cameras...
Camera Health — Last hour (checks every 5 min)
First health check runs 30 seconds after server start...
Alert Email Settings
🔲 Pick a layout above (1 / 2 / 4 / 6 / 8 / 10 / 16), choose your cameras, then click Apply to populate this grid.
Use Sync Playback with a date + time to scrub all cameras together.
System Status
Live snapshot from self-heal watchdog (refreshes every 30s)
Loading…
Reading the latest health snapshot.
Overview
Core Services
Platform Checks
Recent Incidents (last 24h)
Server Health
Real-time system resources, services, and watchdog status
⏳ Loading…
Bandwidth & Cost (B2)
Cloud storage usage, per-camera egress, and a cost estimate at Backblaze's public rates. Ceiling estimate — real invoice lives on Backblaze.
📊 Measured per-camera bandwidth NEW
Loading…
Click Refresh to load.
Source: parsed from /var/log/nginx/access.log. Tracks actual bytes-sent per /live/<camId>/ request — the true viewer traffic. Updates nightly at 02:30. The existing "Bandwidth & Cost" table above still shows the estimate; this card shows reality.
⏳ Loading…
Daily Highlights
Auto-generated Netflix-style reel of each camera's most interesting events. Emailed nightly.
⏳ Loading…
SLA Monitoring
Uptime tracking and SLA compliance per camera
⏳ Loading…
Billing & Usage
Manage pricing, per-client charges, and generate invoices
📊 At a glance — this month
Loading...
Feature Pricing
📊 Cost & Margin Analysis
Per-camera operational cost grouped by site. Revenue is computed from feature pricing × camera options. Margin = revenue − cost.
💸 Internal cost rates — what WE pay (drives margin math)
Infrastructure
Per-feature cost — added per camera when feature is enabled
Margin link
Per-cam total = storage + bandwidth + server + (enabled feature costs).
Loading…
📋 Per-Client Usage Report
Loading…
Loading per-client usage…
Payment Gateway Configuration click to expand
Configure Stripe for direct payments, or set custom payment links per client (QuickBooks, PayPal, etc.)
Webhook URL: https://hdrelay.io/api/stripe/webhook  ·  Events: checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed, checkout.session.expired
Add this endpoint in your Stripe Dashboard → Developers → Webhooks → "Add endpoint", then copy the signing secret here. Leaving secrets blank keeps the saved value.
🔗 Default Payment Link (for all clients without a custom link)
This link appears on every client's invoice unless overridden per-client. Supports QuickBooks, PayPal, Stripe Payment Links, or any URL.
Invoice Tracking
📍 Sites — Generate Per-Site Invoice
One invoice per site, sent to the assigned bill-to client. Manager / accountant / admin users are excluded automatically.
📝 Draft Invoices
Editable invoices not yet sent to the client. Tweak line items / amounts / notes, then click Submit to finalize.
Client Accounts
Publishing
Flow Player
Multi-camera carousel embed — cycles through multiple cameras automatically with arrow controls. Completely separate from single-camera Player Profiles.
Loading…
Administration
Stream Servers
Manage regional DigitalOcean droplets that serve HLS streams to clients. Each camera is assigned to one server — the portal resolves the assignment to the correct HLS URL automatically.
Configured Servers
Loading…
How it works
  1. Each camera has a Stream Server field (dropdown in Manage Cameras → Edit). Default is west.
  2. The portal builds HLS URLs pointing to the assigned server's HLS Base URL for clients.
  3. The regional droplet runs a sync agent (cam-sync-agent.sh) that polls /api/agent/cameras?server=east&token=TOKEN and auto-configures MediaMTX paths for cameras assigned to it.
  4. To move a camera east: edit it → pick East Coast → Save. The east droplet syncs within 60 s.
Sync Agent command (run on the east droplet):
curl https://hdrelay.io/api/agent/cameras?server=east&token=YOUR_SYNC_TOKEN
The cam-sync-agent.sh script (in /opt/camsentry-app/) runs this every 60 s, generates mediamtx paths, and reloads MediaMTX only when the config changes.
East Droplet Quick Setup
1. Provision a DigitalOcean droplet (NYC1 or NYC3, 2–4 vCPU).
2. Install MediaMTX: bash /opt/camsentry-app/east-droplet-setup.sh east.hdrelay.io YOUR_SYNC_TOKEN
3. Point east.hdrelay.io DNS A record at the new droplet IP.
4. In this portal, click + Add Server, key = east, set HLS Base to https://east.hdrelay.io/live, paste the same token.
5. Edit any camera → Stream Server → East Coast → Save. Streams shift within 60 s.
Audit Log
Every admin action — user/camera/permission changes, payment-config edits — recorded with who, when, and from which IP.
Loading…
ℹ Audit log retains the most recent 10,000 entries. Older entries roll off automatically. The log captures key admin actions (user lifecycle, camera lifecycle, payment-config changes); read-only actions are not logged.
Operations Alerts
Internal alerts for the ops team — self-heal events, system health, SSL expiry. For client-facing detection alerts use the Camera Alerts page.
Operations Channels
Pipeline used by self-heal.sh on the droplet. These alerts go to the ops/admin team only — never to customers.
Get one at api.slack.com → your app → Incoming Webhooks → Add New Webhook to Workspace.
Comma-separated. Uses the SMTP provider configured below.
Shared SMTP Infrastructure
Used by both Operations alerts and Camera Alerts. Configure once.
Email Alerts
Use `587` for STARTTLS or `465` for SMTPS.
SMS / Webhook Alerts
Send SMS via Twilio, Vonage, or any webhook that accepts POST with {to, message}.
Alert On These Events
Choose which detection types trigger email/SMS alerts:
Notification Recipients
Only addresses on these lists receive the matching alert. Separate multiple emails with commas, semicolons, or new lines. Leave blank to disable that category.
AI detections (person, vehicle, etc.), motion, and loitering events.
Camera offline/online, disk usage, service health, and other system warnings.
Quiet Hours
Suppress email/SMS alerts during these hours (detection still runs, alerts show in portal).
From To
Camera Alerts
Configure detection & health alerts per camera. These alerts go to your clients/users — not the ops team. Inheritance: camerasite defaultglobal default. Leave a field blank to inherit.
For ops alerts (self-heal, system health), see Operations Alerts.
Pick a camera above to configure its alerts.
My Invoices
View your current service charges and usage
Loading invoice...
My Account
👤
@—
My Cameras
⏳ Loading…
My Sites
⏳ Loading…
🕐 Display Preferences
Change Password
Loitering Detection
Configure per-camera alerts when people linger too long
How Loitering Detection Works
🎯 AI Loitering
Uses AI object tracking to detect when a person stays in the same area beyond the set time. Most accurate — ignores shadows and wind.
📡 Motion Loitering
Uses continuous motion detection. Alerts when motion persists in a zone beyond the set time. Works for any movement, not just people.
One Alert Per Event
Each loitering event triggers only one alert. The person must leave and return to trigger again.
Loading cameras...
Traffic Statistics
Live HLS stream accesses and bandwidth, sourced from server access logs.
Loading…
Viewer Statistics
Total viewers per camera. Live counts auto-refresh every 15 seconds. View tracking must be enabled per camera for monthly/yearly/all-time figures.
Loading viewer statistics…
Viewer Analytics
Live viewers, monthly/yearly totals, country breakdown
Loading viewer analytics...
Detection Analytics
Activity trends, object breakdowns, and peak hours
Loading analytics...
Loading detection settings...
⟨/⟩ Embed Generator
Generate embed code for your cameras — live streams or timelapse
Configuration
Live stream options
Expires: —
💡 Subdomains auto-match (e.g. "example.com" covers *.example.com). Press Enter, comma, or space to add.
Preview
iFrame Embed
Direct Stream URL
HTML Wrapper
WordPress Shortcode
JS Widget (one-liner)
Use when the parent page already has a layout - no iframe, no sandbox, inherits your CSS. SPAs can call HDRelay.refresh() after route changes.
Native HLS.js Player
Power-user option - includes hls.js from a CDN and a real <video> tag. Edit/style it however you want. Works in any framework.
Direct M3U8 (VLC / OBS / native)
Paste this URL into VLC (Media -> Open Network Stream), OBS Browser Source, Roku, or any HLS player. Bypasses the web player entirely.
📺 Smart TV URL NEW
Applies to this TV URL only — doesn't affect iframe embeds.
Opens fullscreen on the TV — no chrome, auto-play, auto-reconnect, screen wake-lock. Works on Samsung Tizen, LG webOS, Roku Browser, Fire TV browser, Chromecast, Android TV. URL is short (6-character ID) so it's typeable on a TV remote. Tip: bookmark this URL on the TV browser and set it as the home page for a one-click lobby display.
🗂 Saved TV URLs
Every TV URL you generate is saved here. Revoke makes the link stop working immediately for the lobby it's deployed to.
Demo Shares
Generate public no-login demo links with QR codes. Collect viewer info via a pre-watch form. Ideal for marketing events, trade shows, and signage.
Loading…
Recordings
Browse, search and replay footage across Server, Cloud and SD — automatically merged and de-duped.
📍 --
💡 Tip — click a date pill below to jump straight to that day.
1
Pick a camera
2
Jump to date & time
— we'll pick the best source automatically.
Nudge
Download range — merge hours into one file click to expand ▾
From
To
Pick a date/time range above, then click Estimate.
How it works: recordings are written as 1-hour segments. The merged MP4 is a lossless concatenation of whole hourly files — the actual output will cover every segment that overlaps your range, which means it may include a few minutes before your start or after your end. For exact-second trimming, download the merged MP4 and clip it in a video editor.
Merged MP4 limited to 24 h per request (disk safety). For longer ranges, use Download TAR — streams raw hourly files in one archive, no disk temp, any length.
Playback
--
📼
Recordings load on demand
Pick a camera above, then load the list — we keep the page snappy by only pulling clips when you ask for them.
Camera
Click any thumbnail to view full size. Auto-capture runs hourly at :13 and fires only if the last capture is older than the configured interval.
Loading…
Camera
Camera Information
⏳ Loading…
Retention Overview
Loading…
Loading cameras…
Cloud (B2): long-term archive · Local: droplet disk cache (fixed 2h) · Events: AI/motion detection clips · Timelapse: snapshot retention. Changes autosave on the row. Set any retention to Off to disable that storage entirely.
Sites
Each site groups cameras by location
Loading sites...
All Sites
Site NameLocationCamerasUsersAction
⏳ Loading…
📷 Cameras
NameSiteIPBrandPTZRetentionAction
⏳ Loading…
🎬 Player Profiles
Give each camera several player "looks" — one for admins, one for public embed, one for a timelapse loop. Each profile gets its own embed URL so you can paste different versions on different sites.
⏳ Loading cameras…
👥 Users
NameUsernameRoleSitesBrandPermissionsAction
⏳ Loading…
Why was this removed?
User permissions in the Manage Users page already control which sidebar items each client sees. The Layout Editor was a second, parallel system doing the same job — a common source of "why can't I see X" confusion. With the editor gone, there is exactly one place to control what a user can see: their permissions row.
To restrict a client's sidebar:
1. Open Manage Users → click Manage on the client's row
2. Toggle off the features they shouldn't see (Live View, Recordings, Detection, etc.)
3. Save — they will see the new layout on their next page load
White Label Branding
Create custom brands — each client sees your logo, colors and company name
Active Brands
⏳ Loading…
Create New Brand
Colors
Live Preview
📹
HD Relay
LIVE
Logout
📹
HD Relay
Secure Camera Portal
SIGN IN
Logo / Icon Upload
No logo
PNG, JPG, SVG or WEBP · Max 2MB · Recommended: 200x60px for banner or 60x60px for icon
Browser Favicon · shows in browser tab
None
PNG, ICO, SVG or WEBP · Max 512KB · Recommended: 32×32 or 64×64
Login Background Image · optional URL, overrides color
Quick Templates · click to apply preset colors
🔗 Client Login URL
Share this URL with your client — the login page renders in their brand colors, logo, and favicon.
Enter a Brand Key above to generate…
Assign Brand to Users