# Cams Biometrics Web API 3.0 -- Python (Flask) Integration Prompt > **Full API documentation:** https://camsbiometrics.com/application/biometric-web-api.html > > **What this file is:** Copy-paste this entire prompt into an AI assistant (Claude, ChatGPT, etc.) to generate a complete, working Python (Flask) implementation for the Cams Biometrics Web API 3.0. The generated code will be a single self-contained file with a callback receiver, REST client, and HTML test interface. --- ## Task First, read the complete API documentation at: **https://camsbiometrics.com/application/biometric-web-api.html** Use that page as the authoritative source for all 38 API operations, JSON schemas, field names, response codes, template types, and merge behaviour. The specification included below in this prompt is a summary -- if there is any conflict, the hosted documentation takes precedence. Then, generate a complete, production-ready Python (Flask) implementation for the **Cams Biometrics Web API 3.0** in a single file. Generate a SINGLE self-contained Python file using Flask (the only pip dependency) and Python standard library. Include: **1. Callback Receiver** -- `POST /callback`: - Reads `request.get_json(force=True)` - Validates AuthToken - Routes based on RealTime sub-keys - Logs to `cams-callbacks.log` - Stores PunchLog in SQLite (`cams_data.db`) - Saves photos as JPEG in `photos/` dir - Returns `{"status":"done"}` **2. REST Client** -- `POST /api/send`: - Accepts JSON `{ "operation": "...", "params": {...} }` - Uses `urllib.request` (no `requests` library) to POST to RESTful endpoint - Builds correct JSON per operation - Returns parsed response **3. HTML Test Interface** -- `GET /`: - Serves inline HTML via Flask's `render_template_string()` - Config fields, operation dropdown, JSON editor, send button, response viewer, callback log - Modern responsive CSS Config at top: ```python CONFIG = { "restful_endpoint": "https://YOUR_RESTFUL_ENDPOINT_URL", "stgid": "YOUR_SERVICE_TAG_ID", "auth_token": "YOUR_AUTH_TOKEN", "callback_auth_token": "YOUR_EXPECTED_CALLBACK_AUTH_TOKEN", "port": 5000, } ``` Include `pip install flask` instruction in a comment. --- ## Cams Biometrics Web API 3.0 -- Complete Specification ### Overview - **Callback API** (Device → Your Server): Real-time events POSTed to your endpoint as raw JSON. You must respond with `{"status":"done"}` (HTTP 200). - **RESTful API** (Your Server → Device): You POST raw JSON to the RESTful endpoint URL (from API Monitor account) with `?stgid=SERVICE_TAG_ID` query parameter. - All payloads are JSON with UTF-8 encoding. Content-Type: application/json. ### Authentication Fields (present in every request) - `AuthToken` (string): 32-char device authentication token - `OperationID` (string): Unique operation identifier - `Time` (string): Timestamp in format "YYYY-MM-DD HH:mm:ss GMT +OFFSET" ### Callback API Operations (Device → Server) -- 11 operations **#1 ManuallyUserDeleted** ```json { "RealTime": { "OperationID": "...", "AuthToken": "...", "Time": "...", "UserDeleted": { "UserID": "1", "OperationTime": "..." } } } ``` **#2 ManuallyDateModified** ```json { "RealTime": { "OperationID": "...", "AuthToken": "...", "Time": "...", "DateModified": { "ModifiedTo": "...", "OperationTime": "..." } } } ``` **#3-9 ManuallyUserUpdated (with various templates)** ```json { "RealTime": { "UserUpdated": { "UserID": "...", "FirstName": "...", "LastName": "...", "UserType": "User", "OperationTime": "...", "Template": [ { "Type": "Card|Password|Fingerprint|Face|Palm|UserPhoto", "UserID": "...", "Data": "...", "Size": "...", "Index": "..." } ] }, "LabelName": "...", "SerialNumber": "...", "OperationID": "...", "AuthToken": "...", "Time": "..." } } ``` ### CRITICAL: Template Merge Behaviour When user data is pushed from the device via Callback (operations #3-#9), templates may arrive ONE AT A TIME or in GROUPS across multiple callbacks. Each callback does NOT contain the full template set -- only the templates that were added or changed. Your callback handler MUST MERGE incoming templates with existing stored templates for that user using Type+Index as the unique key: - Callback 1: Fingerprint Index 0 → store it - Callback 2: Face Index 0 + Card → merge with existing, do NOT delete the fingerprint - Callback 3: Fingerprint Index 0 (updated data) → update/replace only the fingerprint at Index 0 NEVER replace all templates on a callback. Always UPSERT by Type+Index. For types without an Index (Card, Password, UserPhoto), use Type alone as the key. Template types: Card (Data=card number), Password (Data=PIN), Fingerprint (Data=base64, has Size+Index), Face (Data=base64 JPEG, has Size+Index), Palm (Data=base64, has Index), UserPhoto (Data=base64 JPEG). Template array is empty for "WithoutTemplate" variant. **#10 RealTimeAttendancePhoto** ```json { "RealTime": { "Log": { "UserID": "3", "LogPhoto": "", "LogTime": "2020-09-17 07:48:30 GMT +0530" }, "OperationID": "...", "AuthToken": "...", "Time": "..." } } ``` **#11 RealTimePunchLog** (most important -- primary attendance event) ```json { "RealTime": { "OperationID": "...", "LabelName": "...", "SerialNumber": "...", "PunchLog": { "Type": "CheckIn|CheckOut|BreakOut|BreakIn|OverTimeIn|OverTimeOut|MealIn|MealOut", "Temperature": "36.8", "FaceMask": false, "InputType": "Fingerprint|Face|Palm|Card|Password", "UserId": "2", "LogTime": "2020-09-17 07:48:22 GMT +0530" }, "AuthToken": "...", "Time": "..." } } ``` ### RESTful API Operations (Server → Device) -- 27 operations **#12 LoadLog** -- Retrieve attendance logs within a time range Request: `{ "Load": { "PunchLog": { "Filter": { "StartTime": "...", "EndTime": "..." } } }, "OperationID": "...", "AuthToken": "...", "Time": "..." }` Response: `{ "Status": "done", "OperationID": "...", "PunchLog": { "ReturnRowCount": "18", "Log": [ { "Type": "CheckOut", "Temperature": 36.8, "InputType": "Face", "UserID": "2", "LogTime": "...", "FaceMask": false }, ... ] } }` **#13 LoadDeviceInformation** -- Get device hardware details Request: `{ "Load": { "DeviceInformation": "All" }, "OperationID": "...", "AuthToken": "...", "Time": "..." }` Response: `{ "Status": "done", "OperationID": "...", "StatusCode": 0, "DeviceInformation": { "DeviceModel": "...", "Manufacturer": "...", "MacAddress": "...", "StartDate": "...", "EndDate": "...", "LastConnectedTime": "...", "RegisteredUsers": "0", "RegisteredFaces": "0", "ReigsteredFingerprints": "0", "MaximumFacesSupported": "5000", "MaximumFingerprintsSupported": "10000", "MaximumAttendanceLogsSupported": "500000" } }` **#14-27 AddUser variants** -- Register user with various template combinations Base structure: `{ "Add": { "User": { "UserID": "100", "FirstName": "...", "LastName": "...", "UserType": "USER" }, "Template": [ ...template objects... ] }, "OperationID": "...", "AuthToken": "...", "Time": "..." }` Template combinations: Card only (#14), Password only (#15), Face only (#16), Fingerprint only (#17), Palm only (#18), UserPhoto only (#19), Card+Password (#20), Card+Fingerprint (#21), Palm+Face (#22), Card+FP+Face (#23), Card+Palm+Photo (#24), Card+Pwd+FP+Face (#25), Card+Pwd+Palm+Photo (#26), All six (#27). Response: `{ "Status": "done", "OperationID": "...", "StatusCode": 0 }` **#28 AddUserWithoutTemplate** -- Register user with no biometric data `{ "Add": { "User": { "UserID": "1", "FirstName": "...", "LastName": "...", "UserType": "User" } }, "OperationID": "...", "AuthToken": "...", "Time": "..." }` **#29 DeleteUser**: `{ "Delete": { "User": { "UserID": "User123" } }, ... }` **#30 DeleteAllUser**: `{ "Delete": { "User": "All" }, ... }` **#31 DeleteLogAll**: `{ "Delete": { "Log": "All" }, ... }` **#32 DeleteAttendancePhoto**: `{ "Delete": { "PunchPhoto": "All" }, ... }` **#33 ResendAttendance**: `{ "Resend": { "PunchLog": { "Filter": { "StartTime": "...", "EndTime": "..." } } }, "OperationID": "...", "AuthToken": "...", "Time": "..." }` **#34 ResendAllUser**: `{ "Resend": { "User": "All" }, ... }` **#35 EnrollFingerPrint**: `{ "Enroll": { "User": { "UserID": "3", "Type": "Fingerprint", "FirstName": "...", "LastName": "..." } }, ... }` **#36 UpdateAccessTime**: `{ "Update": { "AccessTime": { "UserID": "20", "Start": "2022-07-11 00:00:00", "End": "2022-07-11 23:59:59" } }, ... }` **#37 EnableUser**: `{ "Update": { "User": { "UserID": "1", "Access": "enable" } }, ... }` **#38 DisableUser**: `{ "Update": { "User": { "UserID": "1", "Access": "disable" } }, ... }` ### Response Status Codes (RESTful) 0=Success, 1=Invalid request data, 2=Invalid service tag ID, 3=Invalid request, 4=Invalid encryption, 5=Device offline, 6=Operation timeout, 7=Invalid auth token, 8=User already exists, 9=User not found, 10=Template error, 11=Device memory full, 13=Invalid security key, 15=Feature not supported, 999=Unknown error. --- ## Reference The complete API documentation with all 38 operations, sample request/response payloads, architecture diagram, response status codes, and connection modes is available at: **https://camsbiometrics.com/application/biometric-web-api.html** The generated code should include this URL in: - A comment at the top of the file - The HTML test interface footer (as a link to the full documentation) ## Important Implementation Notes 1. **Generate the COMPLETE file** -- do not abbreviate or use placeholders like "// similar for other operations". Include every operation. 2. **Validate AuthToken** on every inbound callback request. 3. **Generate unique OperationID** for each outbound RESTful request (use UUID or timestamp-based). 4. **Handle errors gracefully** -- catch network errors, JSON parse failures, and return meaningful messages to the test UI. 5. **The HTML test UI must be fully functional** -- operation selection should auto-populate the JSON editor with the correct template including sample values that the user can edit. 6. **Group operations in the dropdown**: Load Operations, Add User Operations, Delete Operations, Resend Operations, Enroll & Update Operations. 7. **Log everything** -- both inbound callbacks and outbound REST requests, with timestamps. 8. **The callback handler MUST always return {"status":"done"}** even if processing fails -- never block the Cams Biometric Gateway (Protocol Engine). 9. **Include setup instructions** as comments at the top of the file (how to install dependencies and run). 10. **Template storage MUST use upsert/merge logic** -- when storing templates from UserUpdated callbacks, use Type+Index as the unique key. Never overwrite all templates for a user; merge the incoming ones with existing stored templates. 11. **Use the configuration block** at the top -- user only needs to edit those values.