API Reference¶
DFACS exposes a local REST API over HTTPS on port 443 (default). All endpoints require an active browser session unless noted otherwise. The API is hosted on the DFACS device itself — accessible from the local network at https://<device-ip>.
Authentication¶
Session-based authentication. Log in via POST /do-login or POST /do-firebase-login. All subsequent requests require the session cookie.
Login¶
Redirects to / on success. Returns 401 on failure.
Status¶
System Status¶
Response:
{
"barcode_port": "COM1",
"relay_port": "COM3",
"last_barcode": "1234567890",
"relay_state": "locked",
"relay_status": "ok"
}
Door Status¶
Response:
{
"relay_state": "locked | unlocked | unknown",
"failsafe_active": false,
"relay_type": "DragonFly"
}
Door Control¶
Manual Open¶
Triggers a timed unlock for the configured RELAY_DEFAULT_DURATION seconds.
Toggle Lock¶
Toggles between locked and permanently-unlocked states.
Access Logs¶
Get Access Logs (HTML)¶
Get Access Logs (JSON)¶
Response:
[
{
"id": 1,
"timestamp": "2026-05-26T14:30:00",
"barcode": "1234567890",
"result": "Allowed",
"reason": null,
"first_name": "Jane",
"last_name": "Smith",
"membership_type": "Premium",
"api_acknowledged": 1
}
]
Result values: Allowed | Denied
Denial reason strings:
| Reason | Trigger |
|---|---|
Expired membership |
API returned expired status |
Past due membership |
Outstanding balance |
Non-sufficient funds |
NSF flag (Antaris) |
Offline - Barcode not found locally |
Offline; barcode not in cache |
Offline - Previously denied: <reason> |
Offline; cached denial |
Revoked |
Removed from member database |
Manually denied |
Manual block via dashboard |
Closed for <Holiday> |
Holiday closure schedule |
Barcode Expired |
Zenoti timestamp validation failed |
Malformed barcode - potential injection attempt |
Failed format validation |
No API client configured |
System not configured |
Security event: <type> |
OSDP security detection |
Barcode Database¶
List Barcodes (HTML)¶
List Barcodes (JSON)¶
Search Barcodes¶
Upload CSV (Standalone mode)¶
CSV format: one barcode per line, no header, UTF-8.
Configuration¶
Get Configuration Page (HTML)¶
Protected by config password (separate from login password, default: admin).
Save Configuration¶
Get Vendor-Specific Fields¶
Returns dynamic form fields for the selected API type.
User Management¶
List Users¶
Response:
[
{
"id": 1,
"username": "admin",
"role_id": 1,
"role_name": "Superadmin",
"created_at": "2026-01-01T00:00:00",
"last_login": "2026-05-26T14:00:00",
"is_active": true
}
]
Create User¶
POST /api/users
Content-Type: application/json
{
"username": "operator1",
"password": "secure_password",
"role_id": 3
}
Update User¶
Delete User¶
Role Management¶
List Roles¶
Create Role¶
POST /api/roles
Content-Type: application/json
{ "name": "Auditor", "permissions": ["access_logs", "statistics"] }
Update Role¶
Delete Role¶
Get Role Permissions¶
Set Role Permissions¶
POST /api/role-permissions/<id>
Content-Type: application/json
{ "permissions": ["access_logs", "configuration", "users"] }
WAN / DFACSWAN Portal¶
WAN Status¶
Test WAN Connection¶
Get WAN Users¶
Returns users synced from the DFACSWAN portal.
Trigger WAN User Sync¶
Audit Logs¶
Get Audit Logs (HTML)¶
Get Audit Logs (JSON)¶
Database Migration¶
Preview Migration¶
Execute Migration¶
POST /migrate_database
Content-Type: application/json
{ "from_type": "zenoti", "to_type": "glofox", "confirmed": true }
Migrates barcode data between vendor-specific tables when switching billing platforms.
Barcode Validation¶
Barcodes must pass format validation before being processed:
- Allowed characters: alphanumeric,
-,_,.,:,# - Max length: 50 characters
- Debounce: duplicate scans within 1.5 seconds are suppressed
- Potential injection attempts are rejected and logged as
Malformed barcode - potential injection attempt