English Română

Version 1.9 | Last updated: July 2026

This document provides a complete reference for integrating with the Metrici QR (QR Code Recognition) system. The API allows you to query QR code detections, manage access control lists (ACL), handle groups, configure automated actions (barrier, email, popup), and retrieve detection statistics.

Table of Contents

Quick Start

Base URL:

http://<server>/api/qr/

Minimal example — get last QR detected:

curl "http://<server>/api/qr/last_qr.php?camera_id=1&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "duration": "0.05"
    },
    "body": [
      {
        "id": 15234,
        "qr_code": "ABC-1234",
        "qr_image": "http://<server>/qr/qr_image/15234",
        "primary_image": "http://<server>/qr/primary_image_resized/15234",
        "seen": "2026/07/30 10:15:22",
        "seen_timestamp": 1722316522,
        "last_seen": "2026/07/30 10:15:22",
        "last_seen_timestamp": 1722316522,
        "camera_id": 1,
        "camera_description": "Entrance Camera",
        "direction": "Inbound",
        "note": "-",
        "action": "open barrier",
        "previous_detection": "not seen",
        "group_id": 5,
        "group_name": "Staff"
      }
    ]
  }
}

Authentication

Most QR API endpoints require authentication via an auth parameter when the server has API key enforcement enabled (use_api_key = 1). The authentication is not required for delete_expired.php.

How to Generate the Auth Key

The auth key is an MD5 hash computed from the concatenation of relevant request parameters and the server's secret API key:

auth = MD5(param1 + param2 + ... + api_key)

The parameters included in the hash depend on the endpoint. Each endpoint documentation lists which parameters are concatenated.

PHP example:

<?php
$api_key = "YOUR_SECRET_API_KEY";  // provided by server admin
$qr_code = "ABC-1234";
$action = "allow";
$camera_id = "1";

// Parameters are concatenated in order (endpoint-specific)
$to_concat = $qr_code . $action . $camera_id;
$auth = md5($to_concat . $api_key);

$url = "http://<server>/api/qr/insert_action.php"
     . "?qr_code={$qr_code}&action={$action}&camera_id={$camera_id}"
     . "&auth={$auth}&output=json";

$response = file_get_contents($url);
echo $response;
?>

Python example:

import hashlib
import requests

api_key = "YOUR_SECRET_API_KEY"
qr_code = "ABC-1234"
action = "allow"
camera_id = "1"

# Concatenate params in order
to_concat = qr_code + action + camera_id
auth = hashlib.md5((to_concat + api_key).encode()).hexdigest()

url = "http://<server>/api/qr/insert_action.php"
params = {
    "qr_code": qr_code,
    "action": action,
    "camera_id": camera_id,
    "auth": auth,
    "output": "json"
}

response = requests.get(url, params=params)
print(response.json())

JavaScript example:

// Note: MD5 not native in browsers — use a library like crypto-js
import CryptoJS from 'crypto-js';

const apiKey = 'YOUR_SECRET_API_KEY';
const qrCode = 'ABC-1234';
const action = 'allow';
const cameraId = '1';

const toConcat = qrCode + action + cameraId;
const auth = CryptoJS.MD5(toConcat + apiKey).toString();

const url = `http://<server>/api/qr/insert_action.php`
  + `?qr_code=${qrCode}&action=${action}&camera_id=${cameraId}`
  + `&auth=${auth}&output=json`;

fetch(url).then(res => res.json()).then(console.log);

Common Parameters

Parameter Type Required Description
auth string Conditional* MD5 authentication hash (required when use_api_key = 1)
output string No Response format: json (default), xml, dump
start string No Start date filter (YYYY-MM-DD). Default: 7 days ago
end string No End date filter (YYYY-MM-DD). Default: today
camera_id integer No Camera ID filter (comma-separated for multiple)
qr_code string No QR code value (for search, insert, delete)
id integer No Action/ACL entry ID
group_id integer No Group ID
Note: All parameters are case-insensitive.

Response Format

JSON (default)

Standard detection response:

{
  "error": false,
  "response": {
    "header": {
      "count": 5,
      "camera_id": 1,
      "duration": "0.05"
    },
    "body": {
      "1": {
        "id": 15234,
        "qr_code": "ABC-1234",
        "qr_image": "http://<server>/qr/qr_image/15234",
        "primary_image": "http://<server>/qr/primary_image_resized/15234",
        "seen": "2026-07-30 10:15:22",
        "camera_id": 1,
        "camera_description": "Entrance Camera",
        "direction": "Inbound",
        "note": "-",
        "group_id": 5,
        "group_name": "Staff"
      }
    }
  }
}

Action/CRUD response:

{
  "error": false,
  "message": "QR Code ACL successfully inserted.",
  "id": 42
}

Error response:

{
  "error": true
}

or:

{
  "error": true,
  "message": "Incorrect authorization key."
}

XML

Set output=xml to receive XML-formatted responses:

<?xml version="1.0"?>
<body>
  <qr>
    <id>15234</id>
    <qr_code>ABC-1234</qr_code>
    <seen>2026-07-30 10:15:22</seen>
  </qr>
</body>

Debug

Set output=dump for PHP var_dump() output.

Detection Endpoints

List QR Detections

Get all QR code detections within a date range, optionally filtered by camera.

Endpoint:

GET /api/qr/list.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of start + end + camera_id + output + api_key
start string No Start date (YYYY-MM-DD). Default: 7 days ago
end string No End date (YYYY-MM-DD). Default: today
camera_id integer No Filter by camera
output string No json (default), xml, dump

Auth hash: MD5(start + end + camera_id + output + api_key)

Example:

curl "http://<server>/api/qr/list.php?start=2026-07-01&end=2026-07-30&camera_id=1&auth=HASH&output=json"

Response fields:

Field Type Description
id integer Detection record ID
qr_code string Detected QR code value
qr_image string URL to QR crop image
primary_image string URL to full frame image
seen string Detection timestamp (Y-m-d H:i:s)
camera_id integer Camera that detected the QR
camera_description string Camera name
direction string Detection direction (Inbound/Outbound)
note string Associated note, or - if none
group_id integer ACL group ID, or 0 if none
group_name string ACL group name, or N/A

Search QR Detections

Search QR detections by code value within a date range.

Endpoint:

GET /api/qr/search.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of qr_code + start + end + output + api_key
qr_code string Yes QR code value (partial match supported via LIKE)
start string No Start date (YYYY-MM-DD). Default: 7 days ago
end string No End date (YYYY-MM-DD). Default: today
output string No json (default), xml, dump

Auth hash: MD5(qr_code + start + end + output + api_key)

Example:

curl "http://<server>/api/qr/search.php?qr_code=ABC-1234&start=2026-07-01&auth=HASH&output=json"

Response: Same structure as list.php, with header.keyword containing the search term.

Last QR Detected

Get the most recently detected QR code(s), optionally per camera. Includes ACL action evaluation.

Endpoint:

GET /api/qr/last_qr.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of camera_id + output + api_key
camera_id integer No Camera ID (comma-separated for multiple cameras)
output string No json (default), xml, dump

Auth hash: MD5(camera_id + output + api_key)

Example:

# Last detection across all cameras
curl "http://<server>/api/qr/last_qr.php?auth=HASH&output=json"

# Last detection per camera
curl "http://<server>/api/qr/last_qr.php?camera_id=1,2,3&auth=HASH&output=json"

Response fields (extended):

Field Type Description
id integer Detection record ID
qr_code string Detected QR code value
qr_image string URL to QR crop image
primary_image string URL to full frame image
seen string Detection timestamp (Y/m/d H:i:s)
seen_timestamp integer Unix timestamp
last_seen string Same as seen
last_seen_timestamp integer Same as seen_timestamp
camera_id integer Camera ID
camera_description string Camera name
direction string Detection direction
note string Associated note
action string Evaluated actions: open barrier, alert email, alert popup, or -
previous_detection string not seen or seen on <camera_name>
group_id integer ACL group ID
group_name string ACL group name

Detection Statistics

Get total and unique QR detection counts within a date range.

Endpoint:

GET /api/qr/stats.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of start + end + camera_id + output + api_key
start string No Start date (YYYY-MM-DD). Default: 7 days ago
end string No End date (YYYY-MM-DD). Default: today
camera_id integer No Filter by camera
output string No json (default), xml, dump

Auth hash: MD5(start + end + camera_id + output + api_key)

Example:

curl "http://<server>/api/qr/stats.php?start=2026-07-01&end=2026-07-30&auth=HASH&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "camera_id": 1,
      "count": 150,
      "duration": "0.08"
    },
    "body": {
      "total_qr": 150,
      "unique_qr": 45
    }
  }
}
Field Type Description
total_qr integer Total number of detections
unique_qr integer Number of unique QR codes detected

Actions / ACL Management

Actions define what happens when a specific QR code is detected: open barriers, send emails, show popups. Actions can be assigned to individual QR codes or inherited from groups.

List All Actions

Get all ACL entries (individual QR code rules).

Endpoint:

GET /api/qr/actions.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of output + api_key
output string No json (default), xml, dump

Auth hash: MD5(output + api_key)

Example:

curl "http://<server>/api/qr/actions.php?auth=HASH&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "count": 3,
      "duration": "0.03"
    },
    "body": {
      "1": {
        "qr_code": "ABC-1234",
        "active": 1,
        "open_barrier_active": 1,
        "open_barrier2_active": 0,
        "send_email_active": 0,
        "send_email_address": "",
        "send_email_message": "",
        "show_popup_active": 0,
        "show_popup_message": "",
        "note": "Staff pass"
      }
    }
  }
}

Response fields:

Field Type Description
qr_code string QR code value (supports wildcards like %ABC%)
active integer 1 = enabled, 0 = disabled
open_barrier_active integer 1 = open primary barrier on detection
open_barrier2_active integer 1 = open secondary barrier
send_email_active integer 1 = send email notification
send_email_address string Email recipient address
send_email_message string Email message body
show_popup_active integer 1 = show popup on monitor
show_popup_message string Popup message text
note string Associated note

Insert Action (Add QR to ACL)

Add a new ACL entry for a QR code. If no camera_id is specified, the action applies to all cameras.

Endpoint:

GET /api/qr/insert_action.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of qr_code + action + camera_id + api_key
qr_code string Yes QR code value
action string Yes Action type (e.g., allow)
camera_id string No Camera ID(s), comma-separated. Omit for all cameras
expire integer No Unix timestamp when action expires. Default: never
open_barrier2 string No Set to any value to enable secondary barrier

Auth hash: MD5(qr_code + action + camera_id + api_key)

Example:

curl "http://<server>/api/qr/insert_action.php?qr_code=ABC-1234&action=allow&camera_id=1,2&expire=1735689600&auth=HASH&output=json"

Response:

{
  "error": false,
  "message": "QR Code ACL successfully inserted.",
  "id": 42
}

Delete Action by QR Code

Remove an ACL entry by QR code value. Optionally scoped to a specific group.

Endpoint:

GET /api/qr/delete_action.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of qr_code + group_id + api_key
qr_code string Yes QR code value
group_id string No Group ID (deletes only if QR belongs to this group)

Auth hash: MD5(qr_code + group_id + api_key)

Example:

curl "http://<server>/api/qr/delete_action.php?qr_code=ABC-1234&auth=HASH&output=json"

Response:

{
  "error": false,
  "message": "QR Code ACL successfully inserted."
}

Delete Action by ID

Remove an ACL entry by its numeric ID.

Endpoint:

GET /api/qr/delete_action_by_id.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of id + api_key
id integer Yes ACL entry ID

Auth hash: MD5(id + api_key)

Example:

curl "http://<server>/api/qr/delete_action_by_id.php?id=42&auth=HASH&output=json"

Response:

{
  "error": false,
  "message": "QR Code ACL successfully deleted."
}

Delete Expired Actions

Remove all ACL entries that have passed their expiration date. This endpoint does not require authentication.

Endpoint:

GET /api/qr/delete_expired.php

Parameters: None

Example:

curl "http://<server>/api/qr/delete_expired.php"

Response:

Expired QR CODE ACL deleted

Groups

Groups allow you to manage ACL settings for multiple QR codes at once. QR codes added to a group inherit the group's settings (timetable, barrier, email, popup, expiry).

List All Groups

Get all ACL groups with their settings and associated cameras.

Endpoint:

GET /api/qr/groups/list.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of output + api_key
output string No json (default), xml, dump

Auth hash: MD5(output + api_key)

Example:

curl "http://<server>/api/qr/groups/list.php?auth=HASH&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "count": 2,
      "duration": "0.04"
    },
    "body": {
      "1": {
        "id": 5,
        "group_name": "Staff",
        "locations_cameras": ["Main / Entrance", "Main / Exit"],
        "active": 1,
        "timetable_id": 1,
        "open_barrier_active": 1,
        "open_barrier2_active": 0,
        "send_email_active": 0,
        "send_email_address": "",
        "send_email_message": "",
        "show_popup_active": 0,
        "show_popup_message": "",
        "action_url": "",
        "defined_at": "2026-01-15 09:00:00",
        "hours_till_expires": 0,
        "expires": "0000-00-00 00:00:00"
      }
    }
  }
}

Response fields:

Field Type Description
id integer Group ID
group_name string Group name
locations_cameras array Associated cameras as "Location / Camera" strings
active integer 1 = enabled
timetable_id integer Timetable ID for access hours
open_barrier_active integer 1 = open primary barrier
open_barrier2_active integer 1 = open secondary barrier
send_email_active integer 1 = send email notification
send_email_address string Email recipient
send_email_message string Email body
show_popup_active integer 1 = show popup
show_popup_message string Popup message
action_url string External webhook URL
defined_at string Group creation timestamp
hours_till_expires integer Hours until group expires
expires string Expiration timestamp

Create Group

Create a new ACL group with settings. If no camera_id is specified, the group applies to all cameras.

Endpoint:

GET /api/qr/groups/insert.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of group_name + timetable_id + camera_id + open_barrier + open_barrier2 + send_email_active + send_email_address + send_email_message + show_popup_active + show_popup_message + action_url + expire + api_key
group_name string Yes Group name
timetable_id integer No Timetable ID. Default: 1
camera_id string No Camera ID(s), comma-separated
open_barrier string No Set to any value to enable primary barrier
open_barrier2 string No Set to any value to enable secondary barrier
send_email_active string No Set to any value to enable email
send_email_address string No Email recipient
send_email_message string No Email body
show_popup_active string No Set to any value to enable popup
show_popup_message string No Popup message text
action_url string No External webhook URL
expire integer No Unix timestamp for expiry

Auth hash: MD5(group_name + timetable_id + camera_id + open_barrier + open_barrier2 + send_email_active + send_email_address + send_email_message + show_popup_active + show_popup_message + action_url + expire + api_key)

Example:

curl "http://<server>/api/qr/groups/insert.php?group_name=Contractors&timetable_id=2&camera_id=1&open_barrier=1&auth=HASH&output=json"

Response:

{
  "error": false,
  "message": "Group ACL successfully inserted."
}

Update Group

Update an existing group's settings.

Endpoint:

GET /api/qr/groups/update.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of all provided parameters + api_key
group_id integer Yes Group ID to update
group_name string No New group name
timetable_id integer No New timetable ID
camera_id string No New camera ID(s), comma-separated
open_barrier string No Enable primary barrier
open_barrier2 string No Enable secondary barrier
send_email_active string No Enable email
send_email_address string No Email recipient
send_email_message string No Email body
show_popup_active string No Enable popup
show_popup_message string No Popup message
action_url string No Webhook URL
expire integer No Expiry timestamp

Auth hash: MD5(group_id + [all provided params] + api_key)

Example:

curl "http://<server>/api/qr/groups/update.php?group_id=5&group_name=Staff+Updated&auth=HASH&output=json"

Response:

{
  "error": false,
  "message": "Group ACL successfully updated."
}

Delete Group

Delete a group. Associated QR codes have their group_id set to 0 (not deleted).

Endpoint:

GET /api/qr/groups/delete.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of group_id + api_key
group_id integer Yes Group ID to delete

Auth hash: MD5(group_id + api_key)

Example:

curl "http://<server>/api/qr/groups/delete.php?group_id=5&auth=HASH&output=json"

Response:

{
  "error": false,
  "message": "GROUP ACL successfully deleted."
}

List QR Codes in Group

Get all QR codes that belong to a specific group.

Endpoint:

GET /api/qr/groups/list_group.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of group_id + output + api_key
group_id integer Yes Group ID
output string No json (default), xml, dump

Auth hash: MD5(group_id + output + api_key)

Example:

curl "http://<server>/api/qr/groups/list_group.php?group_id=5&auth=HASH&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "count": 10,
      "duration": "0.02"
    },
    "body": {
      "1": { "qr_code": "ABC-1234" },
      "2": { "qr_code": "ABC-5678" }
    }
  }
}

Add QR Code to Group (Inherit Settings)

Add a QR code to a group, inheriting all group settings (timetable, barrier, email, popup, expiry).

Endpoint:

GET /api/qr/groups/insert_group_qr.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of qr_code + group_id + api_key
qr_code string Yes QR code value
group_id integer Yes Group ID

Auth hash: MD5(qr_code + group_id + api_key)

Example:

curl "http://<server>/api/qr/groups/insert_group_qr.php?qr_code=NEW-9999&group_id=5&auth=HASH&output=json"

Response:

{
  "error": false,
  "message": "QR Code ACL successfully inserted.",
  "id": 43
}

Add QR Code to Group (Custom Expiry)

Same as above, but allows overriding the group's expiry date.

Endpoint:

GET /api/qr/groups/insert_group_qr_custom.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of qr_code + expire + group_id + api_key
qr_code string Yes QR code value
group_id integer Yes Group ID
expire integer No Custom expiry Unix timestamp. Omit to use group's default

Auth hash: MD5(qr_code + expire + group_id + api_key)

Example:

curl "http://<server>/api/qr/groups/insert_group_qr_custom.php?qr_code=TEMP-0001&group_id=5&expire=1735689600&auth=HASH&output=json"

General

Get Locations

Get all locations.

Endpoint:

GET /api/qr/general/get_locations.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of output + api_key
output string No json (default), xml, dump

Auth hash: MD5(output + api_key)

Example:

curl "http://<server>/api/qr/general/get_locations.php?auth=HASH&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "count": 2,
      "duration": "0.01"
    },
    "body": {
      "1": { "id": 1, "name": "Main Office" },
      "2": { "id": 3, "name": "Warehouse" }
    }
  }
}

Get Cameras

Get all cameras, optionally filtered by location.

Endpoint:

GET /api/qr/general/get_cameras.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of location_id + output + api_key
location_id integer No Filter by location
output string No json (default), xml, dump

Auth hash: MD5(location_id + output + api_key)

Example:

curl "http://<server>/api/qr/general/get_cameras.php?location_id=1&auth=HASH&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "count": 2,
      "duration": "0.02"
    },
    "body": {
      "1": {
        "id": 1,
        "name": "Entrance / Main Office",
        "camera_url": "rtsp://...",
        "open_barrier_url": "http://...",
        "type": "qr",
        "ip_lpr_engine": "192.168.1.100",
        "app_id_lpr_engine": "app1"
      }
    }
  }
}

Response fields:

Field Type Description
id integer Camera ID
name string "Camera Name / Location Name"
camera_url string RTSP stream URL
open_barrier_url string Barrier control URL
type string Camera type
ip_lpr_engine string LPR engine IP
app_id_lpr_engine string LPR engine app ID

Get Timetables

Get all timetables (used to define when ACL actions are active).

Endpoint:

GET /api/qr/general/get_timetable.php

Parameters:

Parameter Type Required Description
auth string Conditional MD5 hash of output + api_key
output string No json (default), xml, dump

Auth hash: MD5(output + api_key)

Example:

curl "http://<server>/api/qr/general/get_timetable.php?auth=HASH&output=json"

Response:

{
  "error": false,
  "response": {
    "header": {
      "count": 3,
      "duration": "0.01"
    },
    "body": {
      "1": {
        "id": 1,
        "name": "24/7",
        "weekdays": "0,1,2,3,4,5,6",
        "start_hour": 0,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 59
      },
      "2": {
        "id": 2,
        "name": "Work Hours",
        "weekdays": "1,2,3,4,5",
        "start_hour": 8,
        "start_minute": 0,
        "end_hour": 18,
        "end_minute": 0
      }
    }
  }
}

Response fields:

Field Type Description
id integer Timetable ID
name string Timetable name
weekdays string Comma-separated day IDs (0=Sunday, 6=Saturday)
start_hour integer Start hour (0-23)
start_minute integer Start minute (0-59)
end_hour integer End hour (0-23)
end_minute integer End minute (0-59)

Error Handling

HTTP Status Codes

Code Description
200 Success — response body contains error: false
200 Logical error — response body contains error: true
— Server error — returns plain text error message

Error Messages

Message Cause
DB connection error! Database unreachable
DB SELECT error! Query failure
Incorrect authorization key. Auth hash mismatch
Error inserting Camera QR Code ACL - QR Code is Required. Missing qr_code parameter
This QR doesn't exists in ACL. QR code not found in ACL
This group doesn't exists in ACL. Group not found
Error inserting Group ACL - Group Name is Required. Missing group_name parameter
Incorrect GROUP ID. Invalid group_id parameter

Integration Flow

Typical workflow — manage QR access:

1. GET /api/qr/general/get_locations.php
   └──> Get all locations

2. GET /api/qr/general/get_cameras.php?location_id=<id>
   └──> Get cameras at location

3. GET /api/qr/general/get_timetable.php
   └──> Get available timetables

4. GET /api/qr/groups/list.php
   └──> Get existing groups

5. GET /api/qr/groups/insert.php?group_name=Visitors&...
   └──> Create new group with settings

6. GET /api/qr/groups/insert_group_qr.php?qr_code=V001&group_id=<id>
   └──> Add QR code to group (inherits settings)

7. GET /api/qr/last_qr.php?camera_id=<id>
   └──> Check last detection and action evaluation

Typical workflow — monitor detections:

1. GET /api/qr/last_qr.php?camera_id=1,2,3
   └──> Get latest detection per camera

2. GET /api/qr/list.php?start=2026-07-01&end=2026-07-30
   └──> Get all detections in date range

3. GET /api/qr/stats.php?start=2026-07-01&end=2026-07-30
   └──> Get total/unique counts

4. GET /api/qr/search.php?qr_code=ABC-1234
   └──> Search specific QR history

Code Examples

PHP — Check Last Detection

<?php
$apiKey = "YOUR_SECRET_API_KEY";
$cameraId = "1";
$output = "json";

$toConcat = $cameraId . $output;
$auth = md5($toConcat . $apiKey);

$url = "http://<server>/api/qr/last_qr.php"
     . "?camera_id={$cameraId}&auth={$auth}&output={$output}";

$response = file_get_contents($url);
$data = json_decode($response, true);

if ($data['error'] === false && !empty($data['response']['body'])) {
    foreach ($data['response']['body'] as $detection) {
        echo "QR: {$detection['qr_code']}\n";
        echo "Seen: {$detection['seen']}\n";
        echo "Action: {$detection['action']}\n";
        echo "Group: {$detection['group_name']}\n";
    }
}
?>

Python — Add QR to Group

import hashlib
import requests

api_key = "YOUR_SECRET_API_KEY"
qr_code = "NEW-0001"
group_id = "5"

to_concat = qr_code + group_id
auth = hashlib.md5((to_concat + api_key).encode()).hexdigest()

url = "http://<server>/api/qr/groups/insert_group_qr.php"
params = {
    "qr_code": qr_code,
    "group_id": group_id,
    "auth": auth,
    "output": "json"
}

response = requests.get(url, params=params)
print(response.json())
# {"error": false, "message": "QR Code ACL successfully inserted.", "id": 43}

cURL — Get Statistics

# Compute auth hash
AUTH=$(echo -n "2026-07-012026-07-30jsonYOUR_API_KEY" | md5sum | awk '{print $1}')

curl -s "http://<server>/api/qr/stats.php" \
  "?start=2026-07-01&end=2026-07-30&auth=${AUTH}&output=json" \
  | jq '.response.body'

Appendix: Endpoint Summary

Endpoint Method Auth Description
list.php GET Yes List QR detections (date range)
search.php GET Yes Search QR by code value
last_qr.php GET Yes Last QR detected per camera
stats.php GET Yes Detection statistics
actions.php GET Yes List all ACL actions
insert_action.php GET Yes Add QR to ACL
delete_action.php GET Yes Delete ACL by QR code
delete_action_by_id.php GET Yes Delete ACL by ID
delete_expired.php GET No Delete expired ACL entries
groups/list.php GET Yes List all groups
groups/insert.php GET Yes Create group
groups/update.php GET Yes Update group
groups/delete.php GET Yes Delete group
groups/list_group.php GET Yes List QR codes in group
groups/insert_group_qr.php GET Yes Add QR to group (inherit)
groups/insert_group_qr_custom.php GET Yes Add QR to group (custom expiry)
general/get_locations.php GET Yes List locations
general/get_cameras.php GET Yes List cameras
general/get_timetable.php GET Yes List timetables