Skip to content

Using the Data

bassem chagra edited this page Oct 26, 2026 · 1 revision

The whole dataset is committed to this repo and released under CC0: use it for anything, commercial or not, with no attribution required (a link back is appreciated). There's no API key, rate limit or build step.

Pick a format

You want… Use
Everything, for scripts or a database data/cameras.json: one array of every camera
A spreadsheet data/cameras.csv: flattened, one row per camera
A pinned, checksummed version cameras.zip attached to each release
One camera or one brand, over HTTP the static JSON API (below)
Only "what does this model look like" (FOV, resolution, type) data/model-enrichment.json: a small extract with no configs or notes
Brand-level RTSP path templates data/rtsp-patterns.json (see Stream URLs by Brand)

The individual source records are in cameras/<brand>/<model>.json, one file per camera. The aggregated files are rebuilt from them on every release.

Static JSON API

Hosted alongside the website. It's read-only, has no key and has no rate limit:

Endpoint Returns
https://www.cctv-database.com/api/index.json API description, camera and brand counts, and when it was generated
https://www.cctv-database.com/api/brands.json every brand, with its slug and camera count
https://www.cctv-database.com/api/brands/{slug}.json one brand and a short list of its cameras
https://www.cctv-database.com/api/cameras/{id}.json one full camera record

Finding a camera

Every record has a unique id (<brand>-<model-slug>, e.g. hikvision-ds-2cd2387g2-lu, axis-p1365). To match hardware you already know, look it up by model or any of the aliases, case-insensitively, and use brand to tell apart the rare cases where two brands share a model code.

Aliases matter: a manufacturer often sells one camera under several order numbers (lens size, housing colour, PAL/NTSC, a regional suffix like -GOV or /SL). The dataset keeps one record per camera and lists the other order numbers as aliases. See the FAQ.

const cameras = require('./data/cameras.json');
const norm = s => s.toUpperCase().replace(/[^A-Z0-9]/g, '');

function findCamera(code, brand) {
  const key = norm(code);
  return cameras.find(c =>
    (!brand || c.brand.toLowerCase() === brand.toLowerCase()) &&
    [c.model, ...(c.aliases || [])].some(m => norm(m) === key));
}

findCamera('DS-2CD2T86G2H-IS2U/SL', 'Hikvision');
import json, re
cams = json.load(open("data/cameras.json"))
norm = lambda s: re.sub(r"[^A-Z0-9]", "", s.upper())

# 4K outdoor cameras with a verified Frigate config
hits = [c for c in cams
        if (c.get("resolution") or {}).get("megapixels", 0) >= 8
        and "outdoor" in (c.get("environment") or [])
        and (c.get("configs") or {}).get("frigate", {}).get("verified")]

Fields worth knowing

Most fields are optional: a missing field means the datasheet doesn't state it, not that the feature is absent. Always use optional access (c.lens?.focal_length_mm). Only id, brand, model, type and resolution are always present.

Field Notes
type bullet, dome, turret, ptz, box, fisheye, panoramic, dual-lens, covert, floodlight, doorbell
resolution {megapixels, max_width, max_height, label}
field_of_view_deg a string, as the datasheet gives it ("104", "110-31", "2.8mm: 104 / 4mm: 89")
night_vision type (ir, color, hybrid, none), range_m, min_lux (black-and-white), min_lux_color
video codecs, max_fps, and streams[] with each stream's resolution, fps and codec
ndaa_compliant true / false only when there is an official basis; omitted otherwise (see the FAQ)
configs ready-made frigate, home_assistant and blue_iris settings (see Stream URLs by Brand)
sources the official URLs every value was taken from
last_verified when a person last checked the record against its sources
added when the camera first appeared in the dataset (from git history)

The full list, with types and allowed values, is in schema/camera.schema.json. COVERAGE.md shows how complete each field is.

Versioning

Releases follow MAJOR.MINOR.PATCH. New cameras and data fixes ship as minor releases, and each release's changes are listed in CHANGELOG.md. If you need reproducible results, pin a release's cameras.zip rather than reading main.

When a camera record is merged or renamed, its old id keeps working on the website (it redirects to the surviving record). If you store ids, re-check them against the changelog when you upgrade.

Clone this wiki locally