Skip to content

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

POST /do-login
Content-Type: application/x-www-form-urlencoded

username=admin&password=<password>

Redirects to / on success. Returns 401 on failure.

POST /do-firebase-login
Content-Type: application/json

{ "id_token": "<firebase_id_token>" }

Status

System Status

GET /status

Response:

{
  "barcode_port": "COM1",
  "relay_port": "COM3",
  "last_barcode": "1234567890",
  "relay_state": "locked",
  "relay_status": "ok"
}

Door Status

GET /api/door-status

Response:

{
  "relay_state": "locked | unlocked | unknown",
  "failsafe_active": false,
  "relay_type": "DragonFly"
}


Door Control

Manual Open

POST /manual-open

Triggers a timed unlock for the configured RELAY_DEFAULT_DURATION seconds.

Toggle Lock

POST /toggle-lock

Toggles between locked and permanently-unlocked states.


Access Logs

Get Access Logs (HTML)

GET /access-logs

Get Access Logs (JSON)

GET /api/access-logs?limit=50&offset=0

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)

GET /barcode-database

List Barcodes (JSON)

GET /api/barcodes

Search Barcodes

POST /search-barcodes
Content-Type: application/json

{ "query": "1234" }

Upload CSV (Standalone mode)

POST /upload-csv
Content-Type: multipart/form-data

file=<csv_file>

CSV format: one barcode per line, no header, UTF-8.


Configuration

Get Configuration Page (HTML)

GET /configuration

Protected by config password (separate from login password, default: admin).

Save Configuration

POST /configuration
Content-Type: application/x-www-form-urlencoded

<key>=<value>&<key>=<value>...

Get Vendor-Specific Fields

GET /api/get_vendor_fields?vendor=Zenoti

Returns dynamic form fields for the selected API type.


User Management

List Users

GET /api/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

PUT /api/users/<id>
Content-Type: application/json

{ "role_id": 2, "is_active": true }

Delete User

DELETE /api/users/<id>

Role Management

List Roles

GET /api/roles

Create Role

POST /api/roles
Content-Type: application/json

{ "name": "Auditor", "permissions": ["access_logs", "statistics"] }

Update Role

PUT /api/roles/<id>

Delete Role

DELETE /api/roles/<id>

Get Role Permissions

GET /api/role-permissions/<id>

Set Role Permissions

POST /api/role-permissions/<id>
Content-Type: application/json

{ "permissions": ["access_logs", "configuration", "users"] }

WAN / DFACSWAN Portal

WAN Status

GET /wan_status

Test WAN Connection

POST /test_wan_connection

Get WAN Users

GET /api/wan-users

Returns users synced from the DFACSWAN portal.

Trigger WAN User Sync

POST /api/wan-users/sync

Audit Logs

Get Audit Logs (HTML)

GET /audit-logs

Get Audit Logs (JSON)

GET /api/audit-logs?limit=50&offset=0

Database Migration

Preview Migration

POST /migrate_preview
Content-Type: application/json

{ "from_type": "zenoti", "to_type": "glofox" }

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