API Reference for Developers and System Integrators
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.
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"
}
]
}
}
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.
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);
| 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 |
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."
}
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>
Set output=dump for PHP var_dump() output.
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 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.
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 |
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 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.
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 |
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
}
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."
}
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."
}
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 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).
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 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 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 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."
}
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 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
}
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"
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 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 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) |
| Code | Description |
|---|---|
200 |
Success — response body contains error: false |
200 |
Logical error — response body contains error: true |
| — | Server error — returns plain text error message |
| 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 |
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
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
<?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";
}
}
?>
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}
# 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'
| 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 |